aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2013-02-02 11:29:28 -0500
committerGrant Likely <grant.likely@secretlab.ca>2013-02-09 05:07:10 -0500
commit83cabe33eb05b51a6239a3df344d89cafac2306c (patch)
treef18d922e7558e73c2aab5e825800ad136ed2fd57 /drivers/gpio/gpiolib.c
parentcb1650d4e0da27e88c1a1bd8fe98c40ae1a5d313 (diff)
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>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c37
1 files changed, 16 insertions, 21 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 585d7c3ce12e..8ccf68bb8a40 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -126,30 +126,25 @@ struct gpio_chip *gpio_to_chip(unsigned gpio)
126/* dynamic allocation of GPIOs, e.g. on a hotplugged device */ 126/* dynamic allocation of GPIOs, e.g. on a hotplugged device */
127static int gpiochip_find_base(int ngpio) 127static int gpiochip_find_base(int ngpio)
128{ 128{
129 int i; 129 struct gpio_chip *chip;
130 int spare = 0; 130 int base = ARCH_NR_GPIOS - ngpio;
131 int base = -ENOSPC; 131
132 132 list_for_each_entry_reverse(chip, &gpio_chips, list) {
133 for (i = ARCH_NR_GPIOS - 1; i >= 0 ; i--) { 133 /* found a free space? */
134 struct gpio_desc *desc = &gpio_desc[i]; 134 if (chip->base + chip->ngpio <= base)
135 struct gpio_chip *chip = desc->chip; 135 break;
136 136 else
137 if (!chip) { 137 /* nope, check the space right before the chip */
138 spare++; 138 base = chip->base - ngpio;
139 if (spare == ngpio) {
140 base = i;
141 break;
142 }
143 } else {
144 spare = 0;
145 if (chip)
146 i -= chip->ngpio - 1;
147 }
148 } 139 }
149 140
150 if (gpio_is_valid(base)) 141 if (gpio_is_valid(base)) {
151 pr_debug("%s: found new base at %d\n", __func__, base); 142 pr_debug("%s: found new base at %d\n", __func__, base);
152 return base; 143 return base;
144 } else {
145 pr_err("%s: cannot find free range\n", __func__);
146 return -ENOSPC;
147 }
153} 148}
154 149
155/* caller ensures gpio is valid and requested, chip->get_direction may sleep */ 150/* caller ensures gpio is valid and requested, chip->get_direction may sleep */