Commit ac917a81 authored by Jonathan Cameron's avatar Jonathan Cameron Committed by Greg Kroah-Hartman

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: default avatarJonathan Cameron <jic23@kernel.org>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 08cd9ef4
...@@ -310,6 +310,7 @@ struct iio_buffer_setup_ops { ...@@ -310,6 +310,7 @@ struct iio_buffer_setup_ops {
* @chan_attr_group: [INTERN] group for all attrs in base directory * @chan_attr_group: [INTERN] group for all attrs in base directory
* @name: [DRIVER] name of the device. * @name: [DRIVER] name of the device.
* @info: [DRIVER] callbacks and constant info from driver * @info: [DRIVER] callbacks and constant info from driver
* @info_exist_lock: [INTERN] lock to prevent use during removal
* @chrdev: [INTERN] associated character device * @chrdev: [INTERN] associated character device
* @groups: [INTERN] attribute groups * @groups: [INTERN] attribute groups
* @groupcounter: [INTERN] index of next attribute group * @groupcounter: [INTERN] index of next attribute group
...@@ -340,6 +341,7 @@ struct iio_dev { ...@@ -340,6 +341,7 @@ struct iio_dev {
struct attribute_group chan_attr_group; struct attribute_group chan_attr_group;
const char *name; const char *name;
const struct iio_info *info; const struct iio_info *info;
struct mutex info_exist_lock;
const struct iio_buffer_setup_ops *setup_ops; const struct iio_buffer_setup_ops *setup_ops;
struct cdev chrdev; struct cdev chrdev;
#define IIO_MAX_GROUPS 6 #define IIO_MAX_GROUPS 6
......
...@@ -594,6 +594,7 @@ struct iio_dev *iio_allocate_device(int sizeof_priv) ...@@ -594,6 +594,7 @@ struct iio_dev *iio_allocate_device(int sizeof_priv)
device_initialize(&dev->dev); device_initialize(&dev->dev);
dev_set_drvdata(&dev->dev, (void *)dev); dev_set_drvdata(&dev->dev, (void *)dev);
mutex_init(&dev->mlock); mutex_init(&dev->mlock);
mutex_init(&dev->info_exist_lock);
dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL);
if (dev->id < 0) { if (dev->id < 0) {
...@@ -718,6 +719,9 @@ EXPORT_SYMBOL(iio_device_register); ...@@ -718,6 +719,9 @@ EXPORT_SYMBOL(iio_device_register);
void iio_device_unregister(struct iio_dev *indio_dev) void iio_device_unregister(struct iio_dev *indio_dev)
{ {
mutex_lock(&indio_dev->info_exist_lock);
indio_dev->info = NULL;
mutex_unlock(&indio_dev->info_exist_lock);
device_unregister(&indio_dev->dev); device_unregister(&indio_dev->dev);
} }
EXPORT_SYMBOL(iio_device_unregister); EXPORT_SYMBOL(iio_device_unregister);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment