From: Haibo Chen <haibo.chen@xxxxxxx> 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@xxxxxxx> --- drivers/gpio/gpiolib.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) 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) { -- 2.25.1