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: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
This commit is contained in:
Lars-Peter Clausen
2013-09-18 21:02:00 +01:00
committed by Jonathan Cameron
parent a87c82e454
commit cadc2125e1
2 changed files with 17 additions and 5 deletions

View File

@@ -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)
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;
} }

View File

@@ -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,
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 @@ error_unlock:
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)
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)
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;
} }