diff --git a/[refs] b/[refs] index 4ff3f28f1702..768e7cba0911 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cb1650d4e0da27e88c1a1bd8fe98c40ae1a5d313 +refs/heads/master: 83cabe33eb05b51a6239a3df344d89cafac2306c diff --git a/trunk/drivers/gpio/gpiolib.c b/trunk/drivers/gpio/gpiolib.c index 585d7c3ce12e..8ccf68bb8a40 100644 --- a/trunk/drivers/gpio/gpiolib.c +++ b/trunk/drivers/gpio/gpiolib.c @@ -126,30 +126,25 @@ struct gpio_chip *gpio_to_chip(unsigned gpio) /* dynamic allocation of GPIOs, e.g. on a hotplugged device */ static int gpiochip_find_base(int ngpio) { - int i; - int spare = 0; - int base = -ENOSPC; - - for (i = ARCH_NR_GPIOS - 1; i >= 0 ; i--) { - struct gpio_desc *desc = &gpio_desc[i]; - struct gpio_chip *chip = desc->chip; - - if (!chip) { - spare++; - if (spare == ngpio) { - base = i; - break; - } - } else { - spare = 0; - if (chip) - i -= chip->ngpio - 1; - } + struct gpio_chip *chip; + int base = ARCH_NR_GPIOS - ngpio; + + list_for_each_entry_reverse(chip, &gpio_chips, list) { + /* found a free space? */ + if (chip->base + chip->ngpio <= base) + break; + else + /* nope, check the space right before the chip */ + base = chip->base - ngpio; } - if (gpio_is_valid(base)) + if (gpio_is_valid(base)) { pr_debug("%s: found new base at %d\n", __func__, base); - return base; + return base; + } else { + pr_err("%s: cannot find free range\n", __func__); + return -ENOSPC; + } } /* caller ensures gpio is valid and requested, chip->get_direction may sleep */