diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/v4l2-dev.c | 52 |
1 files changed, 15 insertions, 37 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 21ffd030611e..cb77197d480e 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/kmod.h> | 26 | #include <linux/kmod.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/smp_lock.h> | ||
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
29 | #include <asm/system.h> | 30 | #include <asm/system.h> |
30 | 31 | ||
@@ -215,28 +216,24 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | |||
215 | return vdev->fops->poll(filp, poll); | 216 | return vdev->fops->poll(filp, poll); |
216 | } | 217 | } |
217 | 218 | ||
218 | static int v4l2_ioctl(struct inode *inode, struct file *filp, | 219 | static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
219 | unsigned int cmd, unsigned long arg) | ||
220 | { | 220 | { |
221 | struct video_device *vdev = video_devdata(filp); | 221 | struct video_device *vdev = video_devdata(filp); |
222 | int ret; | ||
222 | 223 | ||
223 | if (!vdev->fops->ioctl) | ||
224 | return -ENOTTY; | ||
225 | /* Allow ioctl to continue even if the device was unregistered. | 224 | /* Allow ioctl to continue even if the device was unregistered. |
226 | Things like dequeueing buffers might still be useful. */ | 225 | Things like dequeueing buffers might still be useful. */ |
227 | return vdev->fops->ioctl(filp, cmd, arg); | 226 | if (vdev->fops->unlocked_ioctl) { |
228 | } | 227 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); |
229 | 228 | } else if (vdev->fops->ioctl) { | |
230 | static long v4l2_unlocked_ioctl(struct file *filp, | 229 | /* TODO: convert all drivers to unlocked_ioctl */ |
231 | unsigned int cmd, unsigned long arg) | 230 | lock_kernel(); |
232 | { | 231 | ret = vdev->fops->ioctl(filp, cmd, arg); |
233 | struct video_device *vdev = video_devdata(filp); | 232 | unlock_kernel(); |
233 | } else | ||
234 | ret = -ENOTTY; | ||
234 | 235 | ||
235 | if (!vdev->fops->unlocked_ioctl) | 236 | return ret; |
236 | return -ENOTTY; | ||
237 | /* Allow ioctl to continue even if the device was unregistered. | ||
238 | Things like dequeueing buffers might still be useful. */ | ||
239 | return vdev->fops->unlocked_ioctl(filp, cmd, arg); | ||
240 | } | 237 | } |
241 | 238 | ||
242 | #ifdef CONFIG_MMU | 239 | #ifdef CONFIG_MMU |
@@ -307,22 +304,6 @@ static int v4l2_release(struct inode *inode, struct file *filp) | |||
307 | return ret; | 304 | return ret; |
308 | } | 305 | } |
309 | 306 | ||
310 | static const struct file_operations v4l2_unlocked_fops = { | ||
311 | .owner = THIS_MODULE, | ||
312 | .read = v4l2_read, | ||
313 | .write = v4l2_write, | ||
314 | .open = v4l2_open, | ||
315 | .get_unmapped_area = v4l2_get_unmapped_area, | ||
316 | .mmap = v4l2_mmap, | ||
317 | .unlocked_ioctl = v4l2_unlocked_ioctl, | ||
318 | #ifdef CONFIG_COMPAT | ||
319 | .compat_ioctl = v4l2_compat_ioctl32, | ||
320 | #endif | ||
321 | .release = v4l2_release, | ||
322 | .poll = v4l2_poll, | ||
323 | .llseek = no_llseek, | ||
324 | }; | ||
325 | |||
326 | static const struct file_operations v4l2_fops = { | 307 | static const struct file_operations v4l2_fops = { |
327 | .owner = THIS_MODULE, | 308 | .owner = THIS_MODULE, |
328 | .read = v4l2_read, | 309 | .read = v4l2_read, |
@@ -330,7 +311,7 @@ static const struct file_operations v4l2_fops = { | |||
330 | .open = v4l2_open, | 311 | .open = v4l2_open, |
331 | .get_unmapped_area = v4l2_get_unmapped_area, | 312 | .get_unmapped_area = v4l2_get_unmapped_area, |
332 | .mmap = v4l2_mmap, | 313 | .mmap = v4l2_mmap, |
333 | .ioctl = v4l2_ioctl, | 314 | .unlocked_ioctl = v4l2_ioctl, |
334 | #ifdef CONFIG_COMPAT | 315 | #ifdef CONFIG_COMPAT |
335 | .compat_ioctl = v4l2_compat_ioctl32, | 316 | .compat_ioctl = v4l2_compat_ioctl32, |
336 | #endif | 317 | #endif |
@@ -525,10 +506,7 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, | |||
525 | ret = -ENOMEM; | 506 | ret = -ENOMEM; |
526 | goto cleanup; | 507 | goto cleanup; |
527 | } | 508 | } |
528 | if (vdev->fops->unlocked_ioctl) | 509 | vdev->cdev->ops = &v4l2_fops; |
529 | vdev->cdev->ops = &v4l2_unlocked_fops; | ||
530 | else | ||
531 | vdev->cdev->ops = &v4l2_fops; | ||
532 | vdev->cdev->owner = vdev->fops->owner; | 510 | vdev->cdev->owner = vdev->fops->owner; |
533 | ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1); | 511 | ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1); |
534 | if (ret < 0) { | 512 | if (ret < 0) { |