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:
committed by
Jonathan Cameron
parent
a87c82e454
commit
cadc2125e1
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user