aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib-sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpiolib-sysfs.c')
-rw-r--r--drivers/gpio/gpiolib-sysfs.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 7722ed53bd65..af3bc7a8033b 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -551,6 +551,7 @@ static struct class gpio_class = {
551 */ 551 */
552int gpiod_export(struct gpio_desc *desc, bool direction_may_change) 552int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
553{ 553{
554 struct gpio_chip *chip;
554 unsigned long flags; 555 unsigned long flags;
555 int status; 556 int status;
556 const char *ioname = NULL; 557 const char *ioname = NULL;
@@ -568,8 +569,16 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
568 return -EINVAL; 569 return -EINVAL;
569 } 570 }
570 571
572 chip = desc->chip;
573
571 mutex_lock(&sysfs_lock); 574 mutex_lock(&sysfs_lock);
572 575
576 /* check if chip is being removed */
577 if (!chip || !chip->exported) {
578 status = -ENODEV;
579 goto fail_unlock;
580 }
581
573 spin_lock_irqsave(&gpio_lock, flags); 582 spin_lock_irqsave(&gpio_lock, flags);
574 if (!test_bit(FLAG_REQUESTED, &desc->flags) || 583 if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
575 test_bit(FLAG_EXPORT, &desc->flags)) { 584 test_bit(FLAG_EXPORT, &desc->flags)) {
@@ -783,12 +792,15 @@ void gpiochip_unexport(struct gpio_chip *chip)
783{ 792{
784 int status; 793 int status;
785 struct device *dev; 794 struct device *dev;
795 struct gpio_desc *desc;
796 unsigned int i;
786 797
787 mutex_lock(&sysfs_lock); 798 mutex_lock(&sysfs_lock);
788 dev = class_find_device(&gpio_class, NULL, chip, match_export); 799 dev = class_find_device(&gpio_class, NULL, chip, match_export);
789 if (dev) { 800 if (dev) {
790 put_device(dev); 801 put_device(dev);
791 device_unregister(dev); 802 device_unregister(dev);
803 /* prevent further gpiod exports */
792 chip->exported = false; 804 chip->exported = false;
793 status = 0; 805 status = 0;
794 } else 806 } else
@@ -797,6 +809,13 @@ void gpiochip_unexport(struct gpio_chip *chip)
797 809
798 if (status) 810 if (status)
799 chip_dbg(chip, "%s: status %d\n", __func__, status); 811 chip_dbg(chip, "%s: status %d\n", __func__, status);
812
813 /* unregister gpiod class devices owned by sysfs */
814 for (i = 0; i < chip->ngpio; i++) {
815 desc = &chip->desc[i];
816 if (test_and_clear_bit(FLAG_SYSFS, &desc->flags))
817 gpiod_free(desc);
818 }
800} 819}
801 820
802static int __init gpiolib_sysfs_init(void) 821static int __init gpiolib_sysfs_init(void)