diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 37 |
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 */ |
127 | static int gpiochip_find_base(int ngpio) | 127 | static 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 */ |