For GPIO controllers with dynamic GPIO number bases a free base is searched for bottom up. This means that GPIO controllers with fixed GPIO numbers must be registered before any controller with dynamic GPIO number base is registered, because otherwise the GPIO controllers with fixed GPIO numbers find their range occupied and can't be registered anymore. The probe order normally makes sure the SoC internal GPIO controllers with fixed numbers are registered first. With deep probe enabled we can't rely on the probe order anymore, so we need another solution. With this patch a free GPIO number range is searched for top down intead of bottom up, so as long as we have enough space in the ARCH_NR_GPIOS range the SoC internal GPIO controllers find their base unoccupied. GPIO controllers with dynamic GPIO numbers will change their numbers with this patch, but code shouldn't rely on these numbers anyway. Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- drivers/gpio/gpiolib.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f709d11f75..c9b33bcd6c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -414,22 +414,19 @@ free_array: } EXPORT_SYMBOL(gpio_array_to_id); -static int gpiochip_find_base(int start, int ngpio) +static int gpiochip_find_base(int ngpio) { int i; int spare = 0; int base = -ENOSPC; - if (start < 0) - start = 0; - - for (i = start; i < ARCH_NR_GPIOS; i++) { + for (i = ARCH_NR_GPIOS - 1; i >= 0; i--) { struct gpio_chip *chip = gpio_desc[i].chip; if (!chip) { spare++; if (spare == ngpio) { - base = i + 1 - ngpio; + base = i; break; } } else { @@ -614,14 +611,17 @@ int gpiochip_add(struct gpio_chip *chip) { int base, i; - base = gpiochip_find_base(chip->base, chip->ngpio); - if (base < 0) - return base; - - if (chip->base >= 0 && chip->base != base) - return -EBUSY; + if (chip->base >= 0) { + for (i = 0; i < chip->ngpio; i++) { + if (gpio_desc[chip->base + i].chip) + return -EBUSY; + } + } else { + chip->base = gpiochip_find_base(chip->ngpio); + if (chip->base < 0) + return -ENOSPC; + } - chip->base = base; list_add_tail(&chip->list, &chip_list); -- 2.30.2 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox