summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/iio/iio_core.h5
-rw-r--r--drivers/iio/industrialio-buffer.c10
-rw-r--r--drivers/iio/industrialio-core.c18
3 files changed, 27 insertions, 6 deletions
diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h
index 731f5170d5b9..87868fff7d37 100644
--- a/drivers/iio/iio_core.h
+++ b/drivers/iio/iio_core.h
@@ -18,6 +18,11 @@ struct iio_dev;
extern struct device_type iio_device_type;
+struct iio_dev_buffer_pair {
+ struct iio_dev *indio_dev;
+ struct iio_buffer *buffer;
+};
+
#define IIO_IOCTL_UNHANDLED 1
struct iio_ioctl_handler {
struct list_head entry;
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index ea91f9578dee..232a60fe57d2 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -104,8 +104,9 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf,
ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf,
size_t n, loff_t *f_ps)
{
- struct iio_dev *indio_dev = filp->private_data;
- struct iio_buffer *rb = indio_dev->buffer;
+ struct iio_dev_buffer_pair *ib = filp->private_data;
+ struct iio_buffer *rb = ib->buffer;
+ struct iio_dev *indio_dev = ib->indio_dev;
DEFINE_WAIT_FUNC(wait, woken_wake_function);
size_t datum_size;
size_t to_wait;
@@ -170,8 +171,9 @@ ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf,
__poll_t iio_buffer_poll(struct file *filp,
struct poll_table_struct *wait)
{
- struct iio_dev *indio_dev = filp->private_data;
- struct iio_buffer *rb = indio_dev->buffer;
+ struct iio_dev_buffer_pair *ib = filp->private_data;
+ struct iio_buffer *rb = ib->buffer;
+ struct iio_dev *indio_dev = ib->indio_dev;
if (!indio_dev->info || rb == NULL)
return 0;
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index b8b149ccecef..b96acfe13e92 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -1705,13 +1705,24 @@ 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);
+ struct iio_dev_buffer_pair *ib;
if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags))
return -EBUSY;
iio_device_get(indio_dev);
- filp->private_data = indio_dev;
+ ib = kmalloc(sizeof(*ib), GFP_KERNEL);
+ if (!ib) {
+ iio_device_put(indio_dev);
+ clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags);
+ return -ENOMEM;
+ }
+
+ ib->indio_dev = indio_dev;
+ ib->buffer = indio_dev->buffer;
+
+ filp->private_data = ib;
return 0;
}
@@ -1725,8 +1736,10 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp)
*/
static int iio_chrdev_release(struct inode *inode, struct file *filp)
{
+ struct iio_dev_buffer_pair *ib = filp->private_data;
struct iio_dev *indio_dev = container_of(inode->i_cdev,
struct iio_dev, chrdev);
+ kfree(ib);
clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags);
iio_device_put(indio_dev);
@@ -1748,7 +1761,8 @@ void iio_device_ioctl_handler_unregister(struct iio_ioctl_handler *h)
static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
- struct iio_dev *indio_dev = filp->private_data;
+ struct iio_dev_buffer_pair *ib = filp->private_data;
+ struct iio_dev *indio_dev = ib->indio_dev;
struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
struct iio_ioctl_handler *h;
int ret = -ENODEV;