Commit cadc2125 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Jonathan Cameron

iio: fix: Keep a reference to the IIO device for open file descriptors

Make sure that the IIO device is not freed while we still have file descriptors
for it.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent a87c82e4
...@@ -970,6 +970,8 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) ...@@ -970,6 +970,8 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp)
if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags))
return -EBUSY; return -EBUSY;
iio_device_get(indio_dev);
filp->private_data = indio_dev; filp->private_data = indio_dev;
return 0; return 0;
...@@ -983,6 +985,8 @@ static int iio_chrdev_release(struct inode *inode, struct file *filp) ...@@ -983,6 +985,8 @@ static int iio_chrdev_release(struct inode *inode, struct file *filp)
struct iio_dev *indio_dev = container_of(inode->i_cdev, struct iio_dev *indio_dev = container_of(inode->i_cdev,
struct iio_dev, chrdev); struct iio_dev, chrdev);
clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags);
iio_device_put(indio_dev);
return 0; return 0;
} }
......
...@@ -72,7 +72,8 @@ EXPORT_SYMBOL(iio_push_event); ...@@ -72,7 +72,8 @@ EXPORT_SYMBOL(iio_push_event);
static unsigned int iio_event_poll(struct file *filep, static unsigned int iio_event_poll(struct file *filep,
struct poll_table_struct *wait) struct poll_table_struct *wait)
{ {
struct iio_event_interface *ev_int = filep->private_data; struct iio_dev *indio_dev = filep->private_data;
struct iio_event_interface *ev_int = indio_dev->event_interface;
unsigned int events = 0; unsigned int events = 0;
poll_wait(filep, &ev_int->wait, wait); poll_wait(filep, &ev_int->wait, wait);
...@@ -90,7 +91,8 @@ static ssize_t iio_event_chrdev_read(struct file *filep, ...@@ -90,7 +91,8 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
size_t count, size_t count,
loff_t *f_ps) loff_t *f_ps)
{ {
struct iio_event_interface *ev_int = filep->private_data; struct iio_dev *indio_dev = filep->private_data;
struct iio_event_interface *ev_int = indio_dev->event_interface;
unsigned int copied; unsigned int copied;
int ret; int ret;
...@@ -121,7 +123,8 @@ static ssize_t iio_event_chrdev_read(struct file *filep, ...@@ -121,7 +123,8 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
static int iio_event_chrdev_release(struct inode *inode, struct file *filep) static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
{ {
struct iio_event_interface *ev_int = filep->private_data; struct iio_dev *indio_dev = filep->private_data;
struct iio_event_interface *ev_int = indio_dev->event_interface;
spin_lock_irq(&ev_int->wait.lock); spin_lock_irq(&ev_int->wait.lock);
__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
...@@ -133,6 +136,8 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep) ...@@ -133,6 +136,8 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
kfifo_reset_out(&ev_int->det_events); kfifo_reset_out(&ev_int->det_events);
spin_unlock_irq(&ev_int->wait.lock); spin_unlock_irq(&ev_int->wait.lock);
iio_device_put(indio_dev);
return 0; return 0;
} }
...@@ -158,12 +163,15 @@ int iio_event_getfd(struct iio_dev *indio_dev) ...@@ -158,12 +163,15 @@ int iio_event_getfd(struct iio_dev *indio_dev)
return -EBUSY; return -EBUSY;
} }
spin_unlock_irq(&ev_int->wait.lock); spin_unlock_irq(&ev_int->wait.lock);
fd = anon_inode_getfd("iio:event", iio_device_get(indio_dev);
&iio_event_chrdev_fileops, ev_int, O_RDONLY);
fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
indio_dev, O_RDONLY);
if (fd < 0) { if (fd < 0) {
spin_lock_irq(&ev_int->wait.lock); spin_lock_irq(&ev_int->wait.lock);
__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
spin_unlock_irq(&ev_int->wait.lock); spin_unlock_irq(&ev_int->wait.lock);
iio_device_put(indio_dev);
} }
return fd; return fd;
} }
......
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