diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2011-12-19 15:23:45 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-22 13:38:08 -0800 |
commit | bb01443e2cdad4ff5b98e00252e93110d00f4392 (patch) | |
tree | fb57bb214b5721edeb64f050bd4ceeb0892d1eef /drivers/staging | |
parent | e38c79e0825b673d97cecfb36bae9e859e724f1b (diff) | |
download | linux-bb01443e2cdad4ff5b98e00252e93110d00f4392.tar.bz2 |
staging:iio: Make sure a device is only opened once at a time
Our buffer implementation does not support multiple concurrent readers. So we
have to ensure that a device is only opened once at a time. So do the same thing
we do for the event fd and introduce a per device busy flag. The flag gets set
when opening the device and gets cleared when closing the device. If a open is
attempted while the busy flag is set we return -EBUSY.
Acked-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/iio/iio.h | 3 | ||||
-rw-r--r-- | drivers/staging/iio/industrialio-core.c | 17 |
2 files changed, 17 insertions, 3 deletions
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 45b6d759c2e7..be6ced31f65e 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -313,6 +313,7 @@ struct iio_buffer_setup_ops { * @chrdev: [INTERN] associated character device * @groups: [INTERN] attribute groups * @groupcounter: [INTERN] index of next attribute group + * @flags: [INTERN] file ops related flags including busy flag. **/ struct iio_dev { int id; @@ -344,6 +345,8 @@ struct iio_dev { #define IIO_MAX_GROUPS 6 const struct attribute_group *groups[IIO_MAX_GROUPS + 1]; int groupcounter; + + unsigned long flags; }; /** diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 2eef85fa38c7..12d1576a0766 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -1083,9 +1083,18 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) { struct iio_dev *indio_dev = container_of(inode->i_cdev, struct iio_dev, chrdev); + unsigned int ret; + + if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) + return -EBUSY; + filp->private_data = indio_dev; - return iio_chrdev_buffer_open(indio_dev); + ret = iio_chrdev_buffer_open(indio_dev); + if (ret < 0) + clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); + + return ret; } /** @@ -1093,8 +1102,10 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) **/ static int iio_chrdev_release(struct inode *inode, struct file *filp) { - iio_chrdev_buffer_release(container_of(inode->i_cdev, - struct iio_dev, chrdev)); + struct iio_dev *indio_dev = container_of(inode->i_cdev, + struct iio_dev, chrdev); + iio_chrdev_buffer_release(indio_dev); + clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); return 0; } |