gpio: sysfs: release irq after class-device deregistration
authorJohan Hovold <johan@kernel.org>
Mon, 4 May 2015 15:10:35 +0000 (17:10 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Tue, 12 May 2015 08:47:03 +0000 (10:47 +0200)
Make sure to release any irq only after the class device has been
deregistered.

This avoids a race between gpiod_unexport and edge_store, where an irq
could be allocated just before the gpio class device is deregistered
without relying on FLAG_EXPORT and the global sysfs lock.

Note that there is no need to hold the sysfs lock when releasing the irq
after the class device is gone as kernfs will prevent further attribute
operations.

Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpiolib-sysfs.c

index a78dabd4035bf51debfdf413c8c521ec82d65493..e4b079eec9bc43256c13e06d0152a03f8ea0f70f 100644 (file)
@@ -695,7 +695,6 @@ void gpiod_unexport(struct gpio_desc *desc)
 
                dev = class_find_device(&gpio_class, NULL, desc, match_export);
                if (dev) {
-                       gpio_setup_irq(desc, dev, 0);
                        clear_bit(FLAG_SYSFS_DIR, &desc->flags);
                        clear_bit(FLAG_EXPORT, &desc->flags);
                } else
@@ -706,6 +705,11 @@ void gpiod_unexport(struct gpio_desc *desc)
 
        if (dev) {
                device_unregister(dev);
+               /*
+                * Release irq after deregistration to prevent race with
+                * edge_store.
+                */
+               gpio_setup_irq(desc, dev, 0);
                put_device(dev);
        }