diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2013-09-18 16:02:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2013-09-21 07:45:07 -0400 |
commit | cadc2125e140f7122bf1b59d42486cfc778c7286 (patch) | |
tree | 9f4bffd9518d76850a981c877599cc1339de2b0e | |
parent | a87c82e454f184a9473f8cdfd4d304205f585f65 (diff) |
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>
-rw-r--r-- | drivers/iio/industrialio-core.c | 4 | ||||
-rw-r--r-- | drivers/iio/industrialio-event.c | 18 |
2 files changed, 17 insertions, 5 deletions
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 2cc0778a7328..8f7b6c9f92dc 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c | |||
@@ -970,6 +970,8 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) | |||
970 | if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) | 970 | if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) |
971 | return -EBUSY; | 971 | return -EBUSY; |
972 | 972 | ||
973 | iio_device_get(indio_dev); | ||
974 | |||
973 | filp->private_data = indio_dev; | 975 | filp->private_data = indio_dev; |
974 | 976 | ||
975 | return 0; | 977 | return 0; |
@@ -983,6 +985,8 @@ static int iio_chrdev_release(struct inode *inode, struct file *filp) | |||
983 | struct iio_dev *indio_dev = container_of(inode->i_cdev, | 985 | struct iio_dev *indio_dev = container_of(inode->i_cdev, |
984 | struct iio_dev, chrdev); | 986 | struct iio_dev, chrdev); |
985 | clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); | 987 | clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); |
988 | iio_device_put(indio_dev); | ||
989 | |||
986 | return 0; | 990 | return 0; |
987 | } | 991 | } |
988 | 992 | ||
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index f146acd12737..6be65ef5faa9 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c | |||
@@ -72,7 +72,8 @@ EXPORT_SYMBOL(iio_push_event); | |||
72 | static unsigned int iio_event_poll(struct file *filep, | 72 | static unsigned int iio_event_poll(struct file *filep, |
73 | struct poll_table_struct *wait) | 73 | struct poll_table_struct *wait) |
74 | { | 74 | { |
75 | struct iio_event_interface *ev_int = filep->private_data; | 75 | struct iio_dev *indio_dev = filep->private_data; |
76 | struct iio_event_interface *ev_int = indio_dev->event_interface; | ||
76 | unsigned int events = 0; | 77 | unsigned int events = 0; |
77 | 78 | ||
78 | poll_wait(filep, &ev_int->wait, wait); | 79 | poll_wait(filep, &ev_int->wait, wait); |
@@ -90,7 +91,8 @@ static ssize_t iio_event_chrdev_read(struct file *filep, | |||
90 | size_t count, | 91 | size_t count, |
91 | loff_t *f_ps) | 92 | loff_t *f_ps) |
92 | { | 93 | { |
93 | struct iio_event_interface *ev_int = filep->private_data; | 94 | struct iio_dev *indio_dev = filep->private_data; |
95 | struct iio_event_interface *ev_int = indio_dev->event_interface; | ||
94 | unsigned int copied; | 96 | unsigned int copied; |
95 | int ret; | 97 | int ret; |
96 | 98 | ||
@@ -121,7 +123,8 @@ error_unlock: | |||
121 | 123 | ||
122 | static int iio_event_chrdev_release(struct inode *inode, struct file *filep) | 124 | static int iio_event_chrdev_release(struct inode *inode, struct file *filep) |
123 | { | 125 | { |
124 | struct iio_event_interface *ev_int = filep->private_data; | 126 | struct iio_dev *indio_dev = filep->private_data; |
127 | struct iio_event_interface *ev_int = indio_dev->event_interface; | ||
125 | 128 | ||
126 | spin_lock_irq(&ev_int->wait.lock); | 129 | spin_lock_irq(&ev_int->wait.lock); |
127 | __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); | 130 | __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) | |||
133 | kfifo_reset_out(&ev_int->det_events); | 136 | kfifo_reset_out(&ev_int->det_events); |
134 | spin_unlock_irq(&ev_int->wait.lock); | 137 | spin_unlock_irq(&ev_int->wait.lock); |
135 | 138 | ||
139 | iio_device_put(indio_dev); | ||
140 | |||
136 | return 0; | 141 | return 0; |
137 | } | 142 | } |
138 | 143 | ||
@@ -158,12 +163,15 @@ int iio_event_getfd(struct iio_dev *indio_dev) | |||
158 | return -EBUSY; | 163 | return -EBUSY; |
159 | } | 164 | } |
160 | spin_unlock_irq(&ev_int->wait.lock); | 165 | spin_unlock_irq(&ev_int->wait.lock); |
161 | fd = anon_inode_getfd("iio:event", | 166 | iio_device_get(indio_dev); |
162 | &iio_event_chrdev_fileops, ev_int, O_RDONLY); | 167 | |
168 | fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops, | ||
169 | indio_dev, O_RDONLY); | ||
163 | if (fd < 0) { | 170 | if (fd < 0) { |
164 | spin_lock_irq(&ev_int->wait.lock); | 171 | spin_lock_irq(&ev_int->wait.lock); |
165 | __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); | 172 | __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); |
166 | spin_unlock_irq(&ev_int->wait.lock); | 173 | spin_unlock_irq(&ev_int->wait.lock); |
174 | iio_device_put(indio_dev); | ||
167 | } | 175 | } |
168 | return fd; | 176 | return fd; |
169 | } | 177 | } |