diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 123 |
1 files changed, 107 insertions, 16 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d8db2f8ee411..24c62b848bf9 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -43,6 +43,7 @@ struct gpio_desc { | |||
43 | /* flag symbols are bit numbers */ | 43 | /* flag symbols are bit numbers */ |
44 | #define FLAG_REQUESTED 0 | 44 | #define FLAG_REQUESTED 0 |
45 | #define FLAG_IS_OUT 1 | 45 | #define FLAG_IS_OUT 1 |
46 | #define FLAG_RESERVED 2 | ||
46 | 47 | ||
47 | #ifdef CONFIG_DEBUG_FS | 48 | #ifdef CONFIG_DEBUG_FS |
48 | const char *label; | 49 | const char *label; |
@@ -68,6 +69,9 @@ static void gpio_ensure_requested(struct gpio_desc *desc) | |||
68 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { | 69 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { |
69 | pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); | 70 | pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); |
70 | desc_set_label(desc, "[auto]"); | 71 | desc_set_label(desc, "[auto]"); |
72 | if (!try_module_get(desc->chip->owner)) | ||
73 | pr_err("GPIO-%d: module can't be gotten \n", | ||
74 | (int)(desc - gpio_desc)); | ||
71 | } | 75 | } |
72 | } | 76 | } |
73 | 77 | ||
@@ -77,6 +81,76 @@ static inline struct gpio_chip *gpio_to_chip(unsigned gpio) | |||
77 | return gpio_desc[gpio].chip; | 81 | return gpio_desc[gpio].chip; |
78 | } | 82 | } |
79 | 83 | ||
84 | /* dynamic allocation of GPIOs, e.g. on a hotplugged device */ | ||
85 | static int gpiochip_find_base(int ngpio) | ||
86 | { | ||
87 | int i; | ||
88 | int spare = 0; | ||
89 | int base = -ENOSPC; | ||
90 | |||
91 | for (i = ARCH_NR_GPIOS - 1; i >= 0 ; i--) { | ||
92 | struct gpio_desc *desc = &gpio_desc[i]; | ||
93 | struct gpio_chip *chip = desc->chip; | ||
94 | |||
95 | if (!chip && !test_bit(FLAG_RESERVED, &desc->flags)) { | ||
96 | spare++; | ||
97 | if (spare == ngpio) { | ||
98 | base = i; | ||
99 | break; | ||
100 | } | ||
101 | } else { | ||
102 | spare = 0; | ||
103 | if (chip) | ||
104 | i -= chip->ngpio - 1; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | if (gpio_is_valid(base)) | ||
109 | pr_debug("%s: found new base at %d\n", __func__, base); | ||
110 | return base; | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * gpiochip_reserve() - reserve range of gpios to use with platform code only | ||
115 | * @start: starting gpio number | ||
116 | * @ngpio: number of gpios to reserve | ||
117 | * Context: platform init, potentially before irqs or kmalloc will work | ||
118 | * | ||
119 | * Returns a negative errno if any gpio within the range is already reserved | ||
120 | * or registered, else returns zero as a success code. Use this function | ||
121 | * to mark a range of gpios as unavailable for dynamic gpio number allocation, | ||
122 | * for example because its driver support is not yet loaded. | ||
123 | */ | ||
124 | int __init gpiochip_reserve(int start, int ngpio) | ||
125 | { | ||
126 | int ret = 0; | ||
127 | unsigned long flags; | ||
128 | int i; | ||
129 | |||
130 | if (!gpio_is_valid(start) || !gpio_is_valid(start + ngpio)) | ||
131 | return -EINVAL; | ||
132 | |||
133 | spin_lock_irqsave(&gpio_lock, flags); | ||
134 | |||
135 | for (i = start; i < start + ngpio; i++) { | ||
136 | struct gpio_desc *desc = &gpio_desc[i]; | ||
137 | |||
138 | if (desc->chip || test_bit(FLAG_RESERVED, &desc->flags)) { | ||
139 | ret = -EBUSY; | ||
140 | goto err; | ||
141 | } | ||
142 | |||
143 | set_bit(FLAG_RESERVED, &desc->flags); | ||
144 | } | ||
145 | |||
146 | pr_debug("%s: reserved gpios from %d to %d\n", | ||
147 | __func__, start, start + ngpio - 1); | ||
148 | err: | ||
149 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
150 | |||
151 | return ret; | ||
152 | } | ||
153 | |||
80 | /** | 154 | /** |
81 | * gpiochip_add() - register a gpio_chip | 155 | * gpiochip_add() - register a gpio_chip |
82 | * @chip: the chip to register, with chip->base initialized | 156 | * @chip: the chip to register, with chip->base initialized |
@@ -85,38 +159,49 @@ static inline struct gpio_chip *gpio_to_chip(unsigned gpio) | |||
85 | * Returns a negative errno if the chip can't be registered, such as | 159 | * Returns a negative errno if the chip can't be registered, such as |
86 | * because the chip->base is invalid or already associated with a | 160 | * because the chip->base is invalid or already associated with a |
87 | * different chip. Otherwise it returns zero as a success code. | 161 | * different chip. Otherwise it returns zero as a success code. |
162 | * | ||
163 | * If chip->base is negative, this requests dynamic assignment of | ||
164 | * a range of valid GPIOs. | ||
88 | */ | 165 | */ |
89 | int gpiochip_add(struct gpio_chip *chip) | 166 | int gpiochip_add(struct gpio_chip *chip) |
90 | { | 167 | { |
91 | unsigned long flags; | 168 | unsigned long flags; |
92 | int status = 0; | 169 | int status = 0; |
93 | unsigned id; | 170 | unsigned id; |
171 | int base = chip->base; | ||
94 | 172 | ||
95 | /* NOTE chip->base negative is reserved to mean a request for | 173 | if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio)) |
96 | * dynamic allocation. We don't currently support that. | 174 | && base >= 0) { |
97 | */ | ||
98 | |||
99 | if (chip->base < 0 || (chip->base + chip->ngpio) >= ARCH_NR_GPIOS) { | ||
100 | status = -EINVAL; | 175 | status = -EINVAL; |
101 | goto fail; | 176 | goto fail; |
102 | } | 177 | } |
103 | 178 | ||
104 | spin_lock_irqsave(&gpio_lock, flags); | 179 | spin_lock_irqsave(&gpio_lock, flags); |
105 | 180 | ||
181 | if (base < 0) { | ||
182 | base = gpiochip_find_base(chip->ngpio); | ||
183 | if (base < 0) { | ||
184 | status = base; | ||
185 | goto fail_unlock; | ||
186 | } | ||
187 | chip->base = base; | ||
188 | } | ||
189 | |||
106 | /* these GPIO numbers must not be managed by another gpio_chip */ | 190 | /* these GPIO numbers must not be managed by another gpio_chip */ |
107 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 191 | for (id = base; id < base + chip->ngpio; id++) { |
108 | if (gpio_desc[id].chip != NULL) { | 192 | if (gpio_desc[id].chip != NULL) { |
109 | status = -EBUSY; | 193 | status = -EBUSY; |
110 | break; | 194 | break; |
111 | } | 195 | } |
112 | } | 196 | } |
113 | if (status == 0) { | 197 | if (status == 0) { |
114 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 198 | for (id = base; id < base + chip->ngpio; id++) { |
115 | gpio_desc[id].chip = chip; | 199 | gpio_desc[id].chip = chip; |
116 | gpio_desc[id].flags = 0; | 200 | gpio_desc[id].flags = 0; |
117 | } | 201 | } |
118 | } | 202 | } |
119 | 203 | ||
204 | fail_unlock: | ||
120 | spin_unlock_irqrestore(&gpio_lock, flags); | 205 | spin_unlock_irqrestore(&gpio_lock, flags); |
121 | fail: | 206 | fail: |
122 | /* failures here can mean systems won't boot... */ | 207 | /* failures here can mean systems won't boot... */ |
@@ -171,12 +256,15 @@ int gpio_request(unsigned gpio, const char *label) | |||
171 | 256 | ||
172 | spin_lock_irqsave(&gpio_lock, flags); | 257 | spin_lock_irqsave(&gpio_lock, flags); |
173 | 258 | ||
174 | if (gpio >= ARCH_NR_GPIOS) | 259 | if (!gpio_is_valid(gpio)) |
175 | goto done; | 260 | goto done; |
176 | desc = &gpio_desc[gpio]; | 261 | desc = &gpio_desc[gpio]; |
177 | if (desc->chip == NULL) | 262 | if (desc->chip == NULL) |
178 | goto done; | 263 | goto done; |
179 | 264 | ||
265 | if (!try_module_get(desc->chip->owner)) | ||
266 | goto done; | ||
267 | |||
180 | /* NOTE: gpio_request() can be called in early boot, | 268 | /* NOTE: gpio_request() can be called in early boot, |
181 | * before IRQs are enabled. | 269 | * before IRQs are enabled. |
182 | */ | 270 | */ |
@@ -184,8 +272,10 @@ int gpio_request(unsigned gpio, const char *label) | |||
184 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { | 272 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { |
185 | desc_set_label(desc, label ? : "?"); | 273 | desc_set_label(desc, label ? : "?"); |
186 | status = 0; | 274 | status = 0; |
187 | } else | 275 | } else { |
188 | status = -EBUSY; | 276 | status = -EBUSY; |
277 | module_put(desc->chip->owner); | ||
278 | } | ||
189 | 279 | ||
190 | done: | 280 | done: |
191 | if (status) | 281 | if (status) |
@@ -201,7 +291,7 @@ void gpio_free(unsigned gpio) | |||
201 | unsigned long flags; | 291 | unsigned long flags; |
202 | struct gpio_desc *desc; | 292 | struct gpio_desc *desc; |
203 | 293 | ||
204 | if (gpio >= ARCH_NR_GPIOS) { | 294 | if (!gpio_is_valid(gpio)) { |
205 | WARN_ON(extra_checks); | 295 | WARN_ON(extra_checks); |
206 | return; | 296 | return; |
207 | } | 297 | } |
@@ -209,9 +299,10 @@ void gpio_free(unsigned gpio) | |||
209 | spin_lock_irqsave(&gpio_lock, flags); | 299 | spin_lock_irqsave(&gpio_lock, flags); |
210 | 300 | ||
211 | desc = &gpio_desc[gpio]; | 301 | desc = &gpio_desc[gpio]; |
212 | if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) | 302 | if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) { |
213 | desc_set_label(desc, NULL); | 303 | desc_set_label(desc, NULL); |
214 | else | 304 | module_put(desc->chip->owner); |
305 | } else | ||
215 | WARN_ON(extra_checks); | 306 | WARN_ON(extra_checks); |
216 | 307 | ||
217 | spin_unlock_irqrestore(&gpio_lock, flags); | 308 | spin_unlock_irqrestore(&gpio_lock, flags); |
@@ -236,7 +327,7 @@ const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) | |||
236 | { | 327 | { |
237 | unsigned gpio = chip->base + offset; | 328 | unsigned gpio = chip->base + offset; |
238 | 329 | ||
239 | if (gpio >= ARCH_NR_GPIOS || gpio_desc[gpio].chip != chip) | 330 | if (!gpio_is_valid(gpio) || gpio_desc[gpio].chip != chip) |
240 | return NULL; | 331 | return NULL; |
241 | if (test_bit(FLAG_REQUESTED, &gpio_desc[gpio].flags) == 0) | 332 | if (test_bit(FLAG_REQUESTED, &gpio_desc[gpio].flags) == 0) |
242 | return NULL; | 333 | return NULL; |
@@ -267,7 +358,7 @@ int gpio_direction_input(unsigned gpio) | |||
267 | 358 | ||
268 | spin_lock_irqsave(&gpio_lock, flags); | 359 | spin_lock_irqsave(&gpio_lock, flags); |
269 | 360 | ||
270 | if (gpio >= ARCH_NR_GPIOS) | 361 | if (!gpio_is_valid(gpio)) |
271 | goto fail; | 362 | goto fail; |
272 | chip = desc->chip; | 363 | chip = desc->chip; |
273 | if (!chip || !chip->get || !chip->direction_input) | 364 | if (!chip || !chip->get || !chip->direction_input) |
@@ -305,7 +396,7 @@ int gpio_direction_output(unsigned gpio, int value) | |||
305 | 396 | ||
306 | spin_lock_irqsave(&gpio_lock, flags); | 397 | spin_lock_irqsave(&gpio_lock, flags); |
307 | 398 | ||
308 | if (gpio >= ARCH_NR_GPIOS) | 399 | if (!gpio_is_valid(gpio)) |
309 | goto fail; | 400 | goto fail; |
310 | chip = desc->chip; | 401 | chip = desc->chip; |
311 | if (!chip || !chip->set || !chip->direction_output) | 402 | if (!chip || !chip->set || !chip->direction_output) |
@@ -522,7 +613,7 @@ static int gpiolib_show(struct seq_file *s, void *unused) | |||
522 | 613 | ||
523 | /* REVISIT this isn't locked against gpio_chip removal ... */ | 614 | /* REVISIT this isn't locked against gpio_chip removal ... */ |
524 | 615 | ||
525 | for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) { | 616 | for (gpio = 0; gpio_is_valid(gpio); gpio++) { |
526 | if (chip == gpio_desc[gpio].chip) | 617 | if (chip == gpio_desc[gpio].chip) |
527 | continue; | 618 | continue; |
528 | chip = gpio_desc[gpio].chip; | 619 | chip = gpio_desc[gpio].chip; |