aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio
diff options
context:
space:
mode:
authorJonathan Cameron <jic23@kernel.org>2012-02-15 14:48:00 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-24 15:10:02 -0500
commitac917a81117ce0286847666b55dd265f6cda8383 (patch)
treeea5052ebeb55cc59fc0f3fa28df1560ddfa487f3 /drivers/staging/iio
parent08cd9ef4eca0b53cdae190b718e4945408c7d3b8 (diff)
staging:iio:core set the iio_dev.info pointer to null on unregister under lock.
This prevents use of provider callbacks after it has been unregistered. Note that all code using this that can be called from a consumer *must* check the pointer before using and hold the info_exist_lock throughout the usage of the callbacks in info. Signed-off-by: Jonathan Cameron <jic23@kernel.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r--drivers/staging/iio/iio.h2
-rw-r--r--drivers/staging/iio/industrialio-core.c4
2 files changed, 6 insertions, 0 deletions
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index be6ced31f65..478dbe5924c 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -310,6 +310,7 @@ struct iio_buffer_setup_ops {
310 * @chan_attr_group: [INTERN] group for all attrs in base directory 310 * @chan_attr_group: [INTERN] group for all attrs in base directory
311 * @name: [DRIVER] name of the device. 311 * @name: [DRIVER] name of the device.
312 * @info: [DRIVER] callbacks and constant info from driver 312 * @info: [DRIVER] callbacks and constant info from driver
313 * @info_exist_lock: [INTERN] lock to prevent use during removal
313 * @chrdev: [INTERN] associated character device 314 * @chrdev: [INTERN] associated character device
314 * @groups: [INTERN] attribute groups 315 * @groups: [INTERN] attribute groups
315 * @groupcounter: [INTERN] index of next attribute group 316 * @groupcounter: [INTERN] index of next attribute group
@@ -340,6 +341,7 @@ struct iio_dev {
340 struct attribute_group chan_attr_group; 341 struct attribute_group chan_attr_group;
341 const char *name; 342 const char *name;
342 const struct iio_info *info; 343 const struct iio_info *info;
344 struct mutex info_exist_lock;
343 const struct iio_buffer_setup_ops *setup_ops; 345 const struct iio_buffer_setup_ops *setup_ops;
344 struct cdev chrdev; 346 struct cdev chrdev;
345#define IIO_MAX_GROUPS 6 347#define IIO_MAX_GROUPS 6
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index e4824fe8b40..3a2d0802662 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -594,6 +594,7 @@ struct iio_dev *iio_allocate_device(int sizeof_priv)
594 device_initialize(&dev->dev); 594 device_initialize(&dev->dev);
595 dev_set_drvdata(&dev->dev, (void *)dev); 595 dev_set_drvdata(&dev->dev, (void *)dev);
596 mutex_init(&dev->mlock); 596 mutex_init(&dev->mlock);
597 mutex_init(&dev->info_exist_lock);
597 598
598 dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); 599 dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL);
599 if (dev->id < 0) { 600 if (dev->id < 0) {
@@ -718,6 +719,9 @@ EXPORT_SYMBOL(iio_device_register);
718 719
719void iio_device_unregister(struct iio_dev *indio_dev) 720void iio_device_unregister(struct iio_dev *indio_dev)
720{ 721{
722 mutex_lock(&indio_dev->info_exist_lock);
723 indio_dev->info = NULL;
724 mutex_unlock(&indio_dev->info_exist_lock);
721 device_unregister(&indio_dev->dev); 725 device_unregister(&indio_dev->dev);
722} 726}
723EXPORT_SYMBOL(iio_device_unregister); 727EXPORT_SYMBOL(iio_device_unregister);