Skip to content

Commit

Permalink
iio: fix: Keep a reference to the IIO device for open file descriptors
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Lars-Peter Clausen authored and Jonathan Cameron committed Sep 21, 2013
1 parent a87c82e commit cadc212
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
4 changes: 4 additions & 0 deletions drivers/iio/industrialio-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
return -EBUSY;

iio_device_get(indio_dev);

filp->private_data = indio_dev;

return 0;
Expand All @@ -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, chrdev);
clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags);
iio_device_put(indio_dev);

return 0;
}

Expand Down
18 changes: 13 additions & 5 deletions drivers/iio/industrialio-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ EXPORT_SYMBOL(iio_push_event);
static unsigned int iio_event_poll(struct file *filep,
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;

poll_wait(filep, &ev_int->wait, wait);
Expand All @@ -90,7 +91,8 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
size_t count,
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;
int ret;

Expand Down Expand Up @@ -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)
{
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);
__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
Expand All @@ -133,6 +136,8 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
kfifo_reset_out(&ev_int->det_events);
spin_unlock_irq(&ev_int->wait.lock);

iio_device_put(indio_dev);

return 0;
}

Expand All @@ -158,12 +163,15 @@ int iio_event_getfd(struct iio_dev *indio_dev)
return -EBUSY;
}
spin_unlock_irq(&ev_int->wait.lock);
fd = anon_inode_getfd("iio:event",
&iio_event_chrdev_fileops, ev_int, O_RDONLY);
iio_device_get(indio_dev);

fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
indio_dev, O_RDONLY);
if (fd < 0) {
spin_lock_irq(&ev_int->wait.lock);
__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
spin_unlock_irq(&ev_int->wait.lock);
iio_device_put(indio_dev);
}
return fd;
}
Expand Down

0 comments on commit cadc212

Please sign in to comment.