mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-04 09:59:32 +00:00
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>
This commit is contained in:
parent
08cd9ef4ec
commit
ac917a8111
2 changed files with 6 additions and 0 deletions
|
@ -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 {
|
||||||
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)
|
||||||
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);
|
||||||
|
|
||||||
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);
|
||||||
|
|
Loading…
Reference in a new issue