Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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;
}

+13 −5
Original line number Diff line number Diff line
@@ -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;
}