diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 536 |
1 files changed, 523 insertions, 13 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index beaf6b3a37dc..8d2940517c99 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -2,8 +2,11 @@ | |||
2 | #include <linux/module.h> | 2 | #include <linux/module.h> |
3 | #include <linux/irq.h> | 3 | #include <linux/irq.h> |
4 | #include <linux/spinlock.h> | 4 | #include <linux/spinlock.h> |
5 | 5 | #include <linux/device.h> | |
6 | #include <asm/gpio.h> | 6 | #include <linux/err.h> |
7 | #include <linux/debugfs.h> | ||
8 | #include <linux/seq_file.h> | ||
9 | #include <linux/gpio.h> | ||
7 | 10 | ||
8 | 11 | ||
9 | /* Optional implementation infrastructure for GPIO interfaces. | 12 | /* Optional implementation infrastructure for GPIO interfaces. |
@@ -44,6 +47,8 @@ struct gpio_desc { | |||
44 | #define FLAG_REQUESTED 0 | 47 | #define FLAG_REQUESTED 0 |
45 | #define FLAG_IS_OUT 1 | 48 | #define FLAG_IS_OUT 1 |
46 | #define FLAG_RESERVED 2 | 49 | #define FLAG_RESERVED 2 |
50 | #define FLAG_EXPORT 3 /* protected by sysfs_lock */ | ||
51 | #define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */ | ||
47 | 52 | ||
48 | #ifdef CONFIG_DEBUG_FS | 53 | #ifdef CONFIG_DEBUG_FS |
49 | const char *label; | 54 | const char *label; |
@@ -151,6 +156,482 @@ err: | |||
151 | return ret; | 156 | return ret; |
152 | } | 157 | } |
153 | 158 | ||
159 | #ifdef CONFIG_GPIO_SYSFS | ||
160 | |||
161 | /* lock protects against unexport_gpio() being called while | ||
162 | * sysfs files are active. | ||
163 | */ | ||
164 | static DEFINE_MUTEX(sysfs_lock); | ||
165 | |||
166 | /* | ||
167 | * /sys/class/gpio/gpioN... only for GPIOs that are exported | ||
168 | * /direction | ||
169 | * * MAY BE OMITTED if kernel won't allow direction changes | ||
170 | * * is read/write as "in" or "out" | ||
171 | * * may also be written as "high" or "low", initializing | ||
172 | * output value as specified ("out" implies "low") | ||
173 | * /value | ||
174 | * * always readable, subject to hardware behavior | ||
175 | * * may be writable, as zero/nonzero | ||
176 | * | ||
177 | * REVISIT there will likely be an attribute for configuring async | ||
178 | * notifications, e.g. to specify polling interval or IRQ trigger type | ||
179 | * that would for example trigger a poll() on the "value". | ||
180 | */ | ||
181 | |||
182 | static ssize_t gpio_direction_show(struct device *dev, | ||
183 | struct device_attribute *attr, char *buf) | ||
184 | { | ||
185 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
186 | ssize_t status; | ||
187 | |||
188 | mutex_lock(&sysfs_lock); | ||
189 | |||
190 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
191 | status = -EIO; | ||
192 | else | ||
193 | status = sprintf(buf, "%s\n", | ||
194 | test_bit(FLAG_IS_OUT, &desc->flags) | ||
195 | ? "out" : "in"); | ||
196 | |||
197 | mutex_unlock(&sysfs_lock); | ||
198 | return status; | ||
199 | } | ||
200 | |||
201 | static ssize_t gpio_direction_store(struct device *dev, | ||
202 | struct device_attribute *attr, const char *buf, size_t size) | ||
203 | { | ||
204 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
205 | unsigned gpio = desc - gpio_desc; | ||
206 | ssize_t status; | ||
207 | |||
208 | mutex_lock(&sysfs_lock); | ||
209 | |||
210 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
211 | status = -EIO; | ||
212 | else if (sysfs_streq(buf, "high")) | ||
213 | status = gpio_direction_output(gpio, 1); | ||
214 | else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low")) | ||
215 | status = gpio_direction_output(gpio, 0); | ||
216 | else if (sysfs_streq(buf, "in")) | ||
217 | status = gpio_direction_input(gpio); | ||
218 | else | ||
219 | status = -EINVAL; | ||
220 | |||
221 | mutex_unlock(&sysfs_lock); | ||
222 | return status ? : size; | ||
223 | } | ||
224 | |||
225 | static const DEVICE_ATTR(direction, 0644, | ||
226 | gpio_direction_show, gpio_direction_store); | ||
227 | |||
228 | static ssize_t gpio_value_show(struct device *dev, | ||
229 | struct device_attribute *attr, char *buf) | ||
230 | { | ||
231 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
232 | unsigned gpio = desc - gpio_desc; | ||
233 | ssize_t status; | ||
234 | |||
235 | mutex_lock(&sysfs_lock); | ||
236 | |||
237 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
238 | status = -EIO; | ||
239 | else | ||
240 | status = sprintf(buf, "%d\n", gpio_get_value_cansleep(gpio)); | ||
241 | |||
242 | mutex_unlock(&sysfs_lock); | ||
243 | return status; | ||
244 | } | ||
245 | |||
246 | static ssize_t gpio_value_store(struct device *dev, | ||
247 | struct device_attribute *attr, const char *buf, size_t size) | ||
248 | { | ||
249 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
250 | unsigned gpio = desc - gpio_desc; | ||
251 | ssize_t status; | ||
252 | |||
253 | mutex_lock(&sysfs_lock); | ||
254 | |||
255 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
256 | status = -EIO; | ||
257 | else if (!test_bit(FLAG_IS_OUT, &desc->flags)) | ||
258 | status = -EPERM; | ||
259 | else { | ||
260 | long value; | ||
261 | |||
262 | status = strict_strtol(buf, 0, &value); | ||
263 | if (status == 0) { | ||
264 | gpio_set_value_cansleep(gpio, value != 0); | ||
265 | status = size; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | mutex_unlock(&sysfs_lock); | ||
270 | return status; | ||
271 | } | ||
272 | |||
273 | static /*const*/ DEVICE_ATTR(value, 0644, | ||
274 | gpio_value_show, gpio_value_store); | ||
275 | |||
276 | static const struct attribute *gpio_attrs[] = { | ||
277 | &dev_attr_direction.attr, | ||
278 | &dev_attr_value.attr, | ||
279 | NULL, | ||
280 | }; | ||
281 | |||
282 | static const struct attribute_group gpio_attr_group = { | ||
283 | .attrs = (struct attribute **) gpio_attrs, | ||
284 | }; | ||
285 | |||
286 | /* | ||
287 | * /sys/class/gpio/gpiochipN/ | ||
288 | * /base ... matching gpio_chip.base (N) | ||
289 | * /label ... matching gpio_chip.label | ||
290 | * /ngpio ... matching gpio_chip.ngpio | ||
291 | */ | ||
292 | |||
293 | static ssize_t chip_base_show(struct device *dev, | ||
294 | struct device_attribute *attr, char *buf) | ||
295 | { | ||
296 | const struct gpio_chip *chip = dev_get_drvdata(dev); | ||
297 | |||
298 | return sprintf(buf, "%d\n", chip->base); | ||
299 | } | ||
300 | static DEVICE_ATTR(base, 0444, chip_base_show, NULL); | ||
301 | |||
302 | static ssize_t chip_label_show(struct device *dev, | ||
303 | struct device_attribute *attr, char *buf) | ||
304 | { | ||
305 | const struct gpio_chip *chip = dev_get_drvdata(dev); | ||
306 | |||
307 | return sprintf(buf, "%s\n", chip->label ? : ""); | ||
308 | } | ||
309 | static DEVICE_ATTR(label, 0444, chip_label_show, NULL); | ||
310 | |||
311 | static ssize_t chip_ngpio_show(struct device *dev, | ||
312 | struct device_attribute *attr, char *buf) | ||
313 | { | ||
314 | const struct gpio_chip *chip = dev_get_drvdata(dev); | ||
315 | |||
316 | return sprintf(buf, "%u\n", chip->ngpio); | ||
317 | } | ||
318 | static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL); | ||
319 | |||
320 | static const struct attribute *gpiochip_attrs[] = { | ||
321 | &dev_attr_base.attr, | ||
322 | &dev_attr_label.attr, | ||
323 | &dev_attr_ngpio.attr, | ||
324 | NULL, | ||
325 | }; | ||
326 | |||
327 | static const struct attribute_group gpiochip_attr_group = { | ||
328 | .attrs = (struct attribute **) gpiochip_attrs, | ||
329 | }; | ||
330 | |||
331 | /* | ||
332 | * /sys/class/gpio/export ... write-only | ||
333 | * integer N ... number of GPIO to export (full access) | ||
334 | * /sys/class/gpio/unexport ... write-only | ||
335 | * integer N ... number of GPIO to unexport | ||
336 | */ | ||
337 | static ssize_t export_store(struct class *class, const char *buf, size_t len) | ||
338 | { | ||
339 | long gpio; | ||
340 | int status; | ||
341 | |||
342 | status = strict_strtol(buf, 0, &gpio); | ||
343 | if (status < 0) | ||
344 | goto done; | ||
345 | |||
346 | /* No extra locking here; FLAG_SYSFS just signifies that the | ||
347 | * request and export were done by on behalf of userspace, so | ||
348 | * they may be undone on its behalf too. | ||
349 | */ | ||
350 | |||
351 | status = gpio_request(gpio, "sysfs"); | ||
352 | if (status < 0) | ||
353 | goto done; | ||
354 | |||
355 | status = gpio_export(gpio, true); | ||
356 | if (status < 0) | ||
357 | gpio_free(gpio); | ||
358 | else | ||
359 | set_bit(FLAG_SYSFS, &gpio_desc[gpio].flags); | ||
360 | |||
361 | done: | ||
362 | if (status) | ||
363 | pr_debug("%s: status %d\n", __func__, status); | ||
364 | return status ? : len; | ||
365 | } | ||
366 | |||
367 | static ssize_t unexport_store(struct class *class, const char *buf, size_t len) | ||
368 | { | ||
369 | long gpio; | ||
370 | int status; | ||
371 | |||
372 | status = strict_strtol(buf, 0, &gpio); | ||
373 | if (status < 0) | ||
374 | goto done; | ||
375 | |||
376 | status = -EINVAL; | ||
377 | |||
378 | /* reject bogus commands (gpio_unexport ignores them) */ | ||
379 | if (!gpio_is_valid(gpio)) | ||
380 | goto done; | ||
381 | |||
382 | /* No extra locking here; FLAG_SYSFS just signifies that the | ||
383 | * request and export were done by on behalf of userspace, so | ||
384 | * they may be undone on its behalf too. | ||
385 | */ | ||
386 | if (test_and_clear_bit(FLAG_SYSFS, &gpio_desc[gpio].flags)) { | ||
387 | status = 0; | ||
388 | gpio_free(gpio); | ||
389 | } | ||
390 | done: | ||
391 | if (status) | ||
392 | pr_debug("%s: status %d\n", __func__, status); | ||
393 | return status ? : len; | ||
394 | } | ||
395 | |||
396 | static struct class_attribute gpio_class_attrs[] = { | ||
397 | __ATTR(export, 0200, NULL, export_store), | ||
398 | __ATTR(unexport, 0200, NULL, unexport_store), | ||
399 | __ATTR_NULL, | ||
400 | }; | ||
401 | |||
402 | static struct class gpio_class = { | ||
403 | .name = "gpio", | ||
404 | .owner = THIS_MODULE, | ||
405 | |||
406 | .class_attrs = gpio_class_attrs, | ||
407 | }; | ||
408 | |||
409 | |||
410 | /** | ||
411 | * gpio_export - export a GPIO through sysfs | ||
412 | * @gpio: gpio to make available, already requested | ||
413 | * @direction_may_change: true if userspace may change gpio direction | ||
414 | * Context: arch_initcall or later | ||
415 | * | ||
416 | * When drivers want to make a GPIO accessible to userspace after they | ||
417 | * have requested it -- perhaps while debugging, or as part of their | ||
418 | * public interface -- they may use this routine. If the GPIO can | ||
419 | * change direction (some can't) and the caller allows it, userspace | ||
420 | * will see "direction" sysfs attribute which may be used to change | ||
421 | * the gpio's direction. A "value" attribute will always be provided. | ||
422 | * | ||
423 | * Returns zero on success, else an error. | ||
424 | */ | ||
425 | int gpio_export(unsigned gpio, bool direction_may_change) | ||
426 | { | ||
427 | unsigned long flags; | ||
428 | struct gpio_desc *desc; | ||
429 | int status = -EINVAL; | ||
430 | |||
431 | /* can't export until sysfs is available ... */ | ||
432 | if (!gpio_class.p) { | ||
433 | pr_debug("%s: called too early!\n", __func__); | ||
434 | return -ENOENT; | ||
435 | } | ||
436 | |||
437 | if (!gpio_is_valid(gpio)) | ||
438 | goto done; | ||
439 | |||
440 | mutex_lock(&sysfs_lock); | ||
441 | |||
442 | spin_lock_irqsave(&gpio_lock, flags); | ||
443 | desc = &gpio_desc[gpio]; | ||
444 | if (test_bit(FLAG_REQUESTED, &desc->flags) | ||
445 | && !test_bit(FLAG_EXPORT, &desc->flags)) { | ||
446 | status = 0; | ||
447 | if (!desc->chip->direction_input | ||
448 | || !desc->chip->direction_output) | ||
449 | direction_may_change = false; | ||
450 | } | ||
451 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
452 | |||
453 | if (status == 0) { | ||
454 | struct device *dev; | ||
455 | |||
456 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), | ||
457 | desc, "gpio%d", gpio); | ||
458 | if (dev) { | ||
459 | if (direction_may_change) | ||
460 | status = sysfs_create_group(&dev->kobj, | ||
461 | &gpio_attr_group); | ||
462 | else | ||
463 | status = device_create_file(dev, | ||
464 | &dev_attr_value); | ||
465 | if (status != 0) | ||
466 | device_unregister(dev); | ||
467 | } else | ||
468 | status = -ENODEV; | ||
469 | if (status == 0) | ||
470 | set_bit(FLAG_EXPORT, &desc->flags); | ||
471 | } | ||
472 | |||
473 | mutex_unlock(&sysfs_lock); | ||
474 | |||
475 | done: | ||
476 | if (status) | ||
477 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | ||
478 | |||
479 | return status; | ||
480 | } | ||
481 | EXPORT_SYMBOL_GPL(gpio_export); | ||
482 | |||
483 | static int match_export(struct device *dev, void *data) | ||
484 | { | ||
485 | return dev_get_drvdata(dev) == data; | ||
486 | } | ||
487 | |||
488 | /** | ||
489 | * gpio_unexport - reverse effect of gpio_export() | ||
490 | * @gpio: gpio to make unavailable | ||
491 | * | ||
492 | * This is implicit on gpio_free(). | ||
493 | */ | ||
494 | void gpio_unexport(unsigned gpio) | ||
495 | { | ||
496 | struct gpio_desc *desc; | ||
497 | int status = -EINVAL; | ||
498 | |||
499 | if (!gpio_is_valid(gpio)) | ||
500 | goto done; | ||
501 | |||
502 | mutex_lock(&sysfs_lock); | ||
503 | |||
504 | desc = &gpio_desc[gpio]; | ||
505 | if (test_bit(FLAG_EXPORT, &desc->flags)) { | ||
506 | struct device *dev = NULL; | ||
507 | |||
508 | dev = class_find_device(&gpio_class, NULL, desc, match_export); | ||
509 | if (dev) { | ||
510 | clear_bit(FLAG_EXPORT, &desc->flags); | ||
511 | put_device(dev); | ||
512 | device_unregister(dev); | ||
513 | status = 0; | ||
514 | } else | ||
515 | status = -ENODEV; | ||
516 | } | ||
517 | |||
518 | mutex_unlock(&sysfs_lock); | ||
519 | done: | ||
520 | if (status) | ||
521 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | ||
522 | } | ||
523 | EXPORT_SYMBOL_GPL(gpio_unexport); | ||
524 | |||
525 | static int gpiochip_export(struct gpio_chip *chip) | ||
526 | { | ||
527 | int status; | ||
528 | struct device *dev; | ||
529 | |||
530 | /* Many systems register gpio chips for SOC support very early, | ||
531 | * before driver model support is available. In those cases we | ||
532 | * export this later, in gpiolib_sysfs_init() ... here we just | ||
533 | * verify that _some_ field of gpio_class got initialized. | ||
534 | */ | ||
535 | if (!gpio_class.p) | ||
536 | return 0; | ||
537 | |||
538 | /* use chip->base for the ID; it's already known to be unique */ | ||
539 | mutex_lock(&sysfs_lock); | ||
540 | dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip, | ||
541 | "gpiochip%d", chip->base); | ||
542 | if (dev) { | ||
543 | status = sysfs_create_group(&dev->kobj, | ||
544 | &gpiochip_attr_group); | ||
545 | } else | ||
546 | status = -ENODEV; | ||
547 | chip->exported = (status == 0); | ||
548 | mutex_unlock(&sysfs_lock); | ||
549 | |||
550 | if (status) { | ||
551 | unsigned long flags; | ||
552 | unsigned gpio; | ||
553 | |||
554 | spin_lock_irqsave(&gpio_lock, flags); | ||
555 | gpio = chip->base; | ||
556 | while (gpio_desc[gpio].chip == chip) | ||
557 | gpio_desc[gpio++].chip = NULL; | ||
558 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
559 | |||
560 | pr_debug("%s: chip %s status %d\n", __func__, | ||
561 | chip->label, status); | ||
562 | } | ||
563 | |||
564 | return status; | ||
565 | } | ||
566 | |||
567 | static void gpiochip_unexport(struct gpio_chip *chip) | ||
568 | { | ||
569 | int status; | ||
570 | struct device *dev; | ||
571 | |||
572 | mutex_lock(&sysfs_lock); | ||
573 | dev = class_find_device(&gpio_class, NULL, chip, match_export); | ||
574 | if (dev) { | ||
575 | put_device(dev); | ||
576 | device_unregister(dev); | ||
577 | chip->exported = 0; | ||
578 | status = 0; | ||
579 | } else | ||
580 | status = -ENODEV; | ||
581 | mutex_unlock(&sysfs_lock); | ||
582 | |||
583 | if (status) | ||
584 | pr_debug("%s: chip %s status %d\n", __func__, | ||
585 | chip->label, status); | ||
586 | } | ||
587 | |||
588 | static int __init gpiolib_sysfs_init(void) | ||
589 | { | ||
590 | int status; | ||
591 | unsigned long flags; | ||
592 | unsigned gpio; | ||
593 | |||
594 | status = class_register(&gpio_class); | ||
595 | if (status < 0) | ||
596 | return status; | ||
597 | |||
598 | /* Scan and register the gpio_chips which registered very | ||
599 | * early (e.g. before the class_register above was called). | ||
600 | * | ||
601 | * We run before arch_initcall() so chip->dev nodes can have | ||
602 | * registered, and so arch_initcall() can always gpio_export(). | ||
603 | */ | ||
604 | spin_lock_irqsave(&gpio_lock, flags); | ||
605 | for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) { | ||
606 | struct gpio_chip *chip; | ||
607 | |||
608 | chip = gpio_desc[gpio].chip; | ||
609 | if (!chip || chip->exported) | ||
610 | continue; | ||
611 | |||
612 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
613 | status = gpiochip_export(chip); | ||
614 | spin_lock_irqsave(&gpio_lock, flags); | ||
615 | } | ||
616 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
617 | |||
618 | |||
619 | return status; | ||
620 | } | ||
621 | postcore_initcall(gpiolib_sysfs_init); | ||
622 | |||
623 | #else | ||
624 | static inline int gpiochip_export(struct gpio_chip *chip) | ||
625 | { | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static inline void gpiochip_unexport(struct gpio_chip *chip) | ||
630 | { | ||
631 | } | ||
632 | |||
633 | #endif /* CONFIG_GPIO_SYSFS */ | ||
634 | |||
154 | /** | 635 | /** |
155 | * gpiochip_add() - register a gpio_chip | 636 | * gpiochip_add() - register a gpio_chip |
156 | * @chip: the chip to register, with chip->base initialized | 637 | * @chip: the chip to register, with chip->base initialized |
@@ -160,6 +641,11 @@ err: | |||
160 | * because the chip->base is invalid or already associated with a | 641 | * because the chip->base is invalid or already associated with a |
161 | * different chip. Otherwise it returns zero as a success code. | 642 | * different chip. Otherwise it returns zero as a success code. |
162 | * | 643 | * |
644 | * When gpiochip_add() is called very early during boot, so that GPIOs | ||
645 | * can be freely used, the chip->dev device must be registered before | ||
646 | * the gpio framework's arch_initcall(). Otherwise sysfs initialization | ||
647 | * for GPIOs will fail rudely. | ||
648 | * | ||
163 | * If chip->base is negative, this requests dynamic assignment of | 649 | * If chip->base is negative, this requests dynamic assignment of |
164 | * a range of valid GPIOs. | 650 | * a range of valid GPIOs. |
165 | */ | 651 | */ |
@@ -182,7 +668,7 @@ int gpiochip_add(struct gpio_chip *chip) | |||
182 | base = gpiochip_find_base(chip->ngpio); | 668 | base = gpiochip_find_base(chip->ngpio); |
183 | if (base < 0) { | 669 | if (base < 0) { |
184 | status = base; | 670 | status = base; |
185 | goto fail_unlock; | 671 | goto unlock; |
186 | } | 672 | } |
187 | chip->base = base; | 673 | chip->base = base; |
188 | } | 674 | } |
@@ -197,12 +683,23 @@ int gpiochip_add(struct gpio_chip *chip) | |||
197 | if (status == 0) { | 683 | if (status == 0) { |
198 | for (id = base; id < base + chip->ngpio; id++) { | 684 | for (id = base; id < base + chip->ngpio; id++) { |
199 | gpio_desc[id].chip = chip; | 685 | gpio_desc[id].chip = chip; |
200 | gpio_desc[id].flags = 0; | 686 | |
687 | /* REVISIT: most hardware initializes GPIOs as | ||
688 | * inputs (often with pullups enabled) so power | ||
689 | * usage is minimized. Linux code should set the | ||
690 | * gpio direction first thing; but until it does, | ||
691 | * we may expose the wrong direction in sysfs. | ||
692 | */ | ||
693 | gpio_desc[id].flags = !chip->direction_input | ||
694 | ? (1 << FLAG_IS_OUT) | ||
695 | : 0; | ||
201 | } | 696 | } |
202 | } | 697 | } |
203 | 698 | ||
204 | fail_unlock: | 699 | unlock: |
205 | spin_unlock_irqrestore(&gpio_lock, flags); | 700 | spin_unlock_irqrestore(&gpio_lock, flags); |
701 | if (status == 0) | ||
702 | status = gpiochip_export(chip); | ||
206 | fail: | 703 | fail: |
207 | /* failures here can mean systems won't boot... */ | 704 | /* failures here can mean systems won't boot... */ |
208 | if (status) | 705 | if (status) |
@@ -239,6 +736,10 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
239 | } | 736 | } |
240 | 737 | ||
241 | spin_unlock_irqrestore(&gpio_lock, flags); | 738 | spin_unlock_irqrestore(&gpio_lock, flags); |
739 | |||
740 | if (status == 0) | ||
741 | gpiochip_unexport(chip); | ||
742 | |||
242 | return status; | 743 | return status; |
243 | } | 744 | } |
244 | EXPORT_SYMBOL_GPL(gpiochip_remove); | 745 | EXPORT_SYMBOL_GPL(gpiochip_remove); |
@@ -296,6 +797,8 @@ void gpio_free(unsigned gpio) | |||
296 | return; | 797 | return; |
297 | } | 798 | } |
298 | 799 | ||
800 | gpio_unexport(gpio); | ||
801 | |||
299 | spin_lock_irqsave(&gpio_lock, flags); | 802 | spin_lock_irqsave(&gpio_lock, flags); |
300 | 803 | ||
301 | desc = &gpio_desc[gpio]; | 804 | desc = &gpio_desc[gpio]; |
@@ -534,10 +1037,6 @@ EXPORT_SYMBOL_GPL(gpio_set_value_cansleep); | |||
534 | 1037 | ||
535 | #ifdef CONFIG_DEBUG_FS | 1038 | #ifdef CONFIG_DEBUG_FS |
536 | 1039 | ||
537 | #include <linux/debugfs.h> | ||
538 | #include <linux/seq_file.h> | ||
539 | |||
540 | |||
541 | static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | 1040 | static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) |
542 | { | 1041 | { |
543 | unsigned i; | 1042 | unsigned i; |
@@ -614,17 +1113,28 @@ static int gpiolib_show(struct seq_file *s, void *unused) | |||
614 | /* REVISIT this isn't locked against gpio_chip removal ... */ | 1113 | /* REVISIT this isn't locked against gpio_chip removal ... */ |
615 | 1114 | ||
616 | for (gpio = 0; gpio_is_valid(gpio); gpio++) { | 1115 | for (gpio = 0; gpio_is_valid(gpio); gpio++) { |
1116 | struct device *dev; | ||
1117 | |||
617 | if (chip == gpio_desc[gpio].chip) | 1118 | if (chip == gpio_desc[gpio].chip) |
618 | continue; | 1119 | continue; |
619 | chip = gpio_desc[gpio].chip; | 1120 | chip = gpio_desc[gpio].chip; |
620 | if (!chip) | 1121 | if (!chip) |
621 | continue; | 1122 | continue; |
622 | 1123 | ||
623 | seq_printf(s, "%sGPIOs %d-%d, %s%s:\n", | 1124 | seq_printf(s, "%sGPIOs %d-%d", |
624 | started ? "\n" : "", | 1125 | started ? "\n" : "", |
625 | chip->base, chip->base + chip->ngpio - 1, | 1126 | chip->base, chip->base + chip->ngpio - 1); |
626 | chip->label ? : "generic", | 1127 | dev = chip->dev; |
627 | chip->can_sleep ? ", can sleep" : ""); | 1128 | if (dev) |
1129 | seq_printf(s, ", %s/%s", | ||
1130 | dev->bus ? dev->bus->name : "no-bus", | ||
1131 | dev->bus_id); | ||
1132 | if (chip->label) | ||
1133 | seq_printf(s, ", %s", chip->label); | ||
1134 | if (chip->can_sleep) | ||
1135 | seq_printf(s, ", can sleep"); | ||
1136 | seq_printf(s, ":\n"); | ||
1137 | |||
628 | started = 1; | 1138 | started = 1; |
629 | if (chip->dbg_show) | 1139 | if (chip->dbg_show) |
630 | chip->dbg_show(s, chip); | 1140 | chip->dbg_show(s, chip); |