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:
parent
a87c82e454
commit
cadc2125e1
2 changed files with 17 additions and 5 deletions
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue