diff mbox series

[v2] gpio: Allow setting gpio device id via device tree alias

Message ID 1647927649-9907-1-git-send-email-haibo.chen@nxp.com
State New
Headers show
Series [v2] gpio: Allow setting gpio device id via device tree alias | expand

Commit Message

Bough Chen March 22, 2022, 5:40 a.m. UTC
From: Haibo Chen <haibo.chen@nxp.com>

For some SoCs which contain different cores, like few ARM A cores
and few ARM M cores. Some GPIO controllers like GPIO3/GPIO4/GPIO5
belong to A core domain, some GPIO controllers like GPIO1/GPIO2
belong to M core domain. Linux only cover A cores, without gpio
alias, we can get gpiochip0/gpiochip1/gpiochip2 to map the real
GPIO3/GPIO4/GPIO5, it's difficult for users to identify this map
relation, and hardcode the gpio device index. With gpio alias,
we can easily make gpiochip3 map to GPIO3, gpiochip4 map to GPIO4.
For GPIO controllers do not claim the alias, it will get one id
which larger than all the claimed aliases.

Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
---
 drivers/gpio/gpiolib.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

Comments

Linus Walleij March 27, 2022, 11:07 p.m. UTC | #1
On Tue, Mar 22, 2022 at 11:16 AM Bough Chen <haibo.chen@nxp.com> wrote:

> For users, usually, they will open /dev/gpiochipx to handle gpio related option.

That makes sense, it is intuitive in a way.

> By the way, how can user get the labels and device names of GPIO chips?

The way to get metadata for any /dev/* device such as topology on
buses is through sysfs.

It is also possible to get labels for all gpiochips by iterating over them.

The most user-friendly thing to do is however to make use of libgpiod
and associated example tools such as gpiodetect:
https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about/

Yours,
Linus Walleij
diff mbox series

Patch

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 56d090258d62..3d24351a33db 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -495,7 +495,7 @@  static void gpiodevice_release(struct device *dev)
 	list_del(&gdev->list);
 	spin_unlock_irqrestore(&gpio_lock, flags);
 
-	ida_free(&gpio_ida, gdev->id);
+	ida_simple_remove(&gpio_ida, gdev->id);
 	kfree_const(gdev->label);
 	kfree(gdev->descs);
 	kfree(gdev);
@@ -594,6 +594,7 @@  int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
 	unsigned long flags;
 	int base = gc->base;
 	unsigned int i;
+	int alias_id, first_dynamic;
 	int ret = 0;
 	u32 ngpios;
 
@@ -623,11 +624,20 @@  int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
 	 */
 	gdev->dev.fwnode = dev_fwnode(&gdev->dev) ?: fwnode;
 
-	gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
-	if (gdev->id < 0) {
-		ret = gdev->id;
-		goto err_free_gdev;
+	alias_id = of_alias_get_id(gdev->dev.of_node, "gpio");
+	if (alias_id < 0) {
+		first_dynamic = of_alias_get_highest_id("gpio");
+		if (first_dynamic < 0)
+			first_dynamic = 0;
+		else
+			first_dynamic++;
+		alias_id = ida_simple_get(&gpio_ida, first_dynamic, 0, GFP_KERNEL);
+		if (alias_id < 0) {
+			ret = alias_id;
+			goto err_free_gdev;
+		}
 	}
+	gdev->id = alias_id;
 
 	ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
 	if (ret)
@@ -821,7 +831,7 @@  int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
 err_free_dev_name:
 	kfree(dev_name(&gdev->dev));
 err_free_ida:
-	ida_free(&gpio_ida, gdev->id);
+	ida_simple_remove(&gpio_ida, gdev->id);
 err_free_gdev:
 	/* failures here can mean systems won't boot... */
 	if (ret != -EPROBE_DEFER) {