gpiolib: use gpio_chips list in gpiochip_find_base

Re-implement gpiochip_find_base using the list of chips instead of the
global gpio_desc[] array. This makes it both simpler and more efficient,
and is needed to remove the global descriptors array.

The new code should preserve the exact same GPIO number assignment
policy as the code it is replacing. There shouldn't be any visible
change to the assigned GPIO numbers.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
[grant.likely: Added comment about assignment policy]
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
This commit is contained in:
Alexandre Courbot 2013-02-03 01:29:28 +09:00 committed by Grant Likely
parent cb1650d4e0
commit 83cabe33eb
1 changed files with 15 additions and 20 deletions

View File

@ -126,30 +126,25 @@ struct gpio_chip *gpio_to_chip(unsigned gpio)
/* dynamic allocation of GPIOs, e.g. on a hotplugged device */ /* dynamic allocation of GPIOs, e.g. on a hotplugged device */
static int gpiochip_find_base(int ngpio) static int gpiochip_find_base(int ngpio)
{ {
int i; struct gpio_chip *chip;
int spare = 0; int base = ARCH_NR_GPIOS - ngpio;
int base = -ENOSPC;
for (i = ARCH_NR_GPIOS - 1; i >= 0 ; i--) { list_for_each_entry_reverse(chip, &gpio_chips, list) {
struct gpio_desc *desc = &gpio_desc[i]; /* found a free space? */
struct gpio_chip *chip = desc->chip; if (chip->base + chip->ngpio <= base)
break;
if (!chip) { else
spare++; /* nope, check the space right before the chip */
if (spare == ngpio) { base = chip->base - ngpio;
base = i;
break;
}
} else {
spare = 0;
if (chip)
i -= chip->ngpio - 1;
}
} }
if (gpio_is_valid(base)) if (gpio_is_valid(base)) {
pr_debug("%s: found new base at %d\n", __func__, 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 */ /* caller ensures gpio is valid and requested, chip->get_direction may sleep */