summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2015-05-04 17:10:35 +0200
committerLinus Walleij <linus.walleij@linaro.org>2015-05-12 10:47:03 +0200
commit54d9acd7540995b06a47974e3d06da7f68df9d4a (patch)
tree9d86f162d0488d13b5bca406e8f070e47802bb4d /drivers/gpio
parent6beac9d1aa9bf104b01816852131fa175c0a178b (diff)
downloadop-kernel-dev-54d9acd7540995b06a47974e3d06da7f68df9d4a.zip
op-kernel-dev-54d9acd7540995b06a47974e3d06da7f68df9d4a.tar.gz
gpio: sysfs: release irq after class-device deregistration
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>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpiolib-sysfs.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index a78dabd..e4b079e 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -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);
}
OpenPOWER on IntegriCloud