diff options
Diffstat (limited to 'drivers/media/video/v4l2-dev.c')
-rw-r--r-- | drivers/media/video/v4l2-dev.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index b1f0923212e6..2c4feffa4939 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -274,11 +274,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, | |||
274 | 274 | ||
275 | if (!vdev->fops->read) | 275 | if (!vdev->fops->read) |
276 | return -EINVAL; | 276 | return -EINVAL; |
277 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) | 277 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && |
278 | mutex_lock_interruptible(vdev->lock)) | ||
278 | return -ERESTARTSYS; | 279 | return -ERESTARTSYS; |
279 | if (video_is_registered(vdev)) | 280 | if (video_is_registered(vdev)) |
280 | ret = vdev->fops->read(filp, buf, sz, off); | 281 | ret = vdev->fops->read(filp, buf, sz, off); |
281 | if (vdev->lock) | 282 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
282 | mutex_unlock(vdev->lock); | 283 | mutex_unlock(vdev->lock); |
283 | return ret; | 284 | return ret; |
284 | } | 285 | } |
@@ -291,11 +292,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
291 | 292 | ||
292 | if (!vdev->fops->write) | 293 | if (!vdev->fops->write) |
293 | return -EINVAL; | 294 | return -EINVAL; |
294 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) | 295 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && |
296 | mutex_lock_interruptible(vdev->lock)) | ||
295 | return -ERESTARTSYS; | 297 | return -ERESTARTSYS; |
296 | if (video_is_registered(vdev)) | 298 | if (video_is_registered(vdev)) |
297 | ret = vdev->fops->write(filp, buf, sz, off); | 299 | ret = vdev->fops->write(filp, buf, sz, off); |
298 | if (vdev->lock) | 300 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
299 | mutex_unlock(vdev->lock); | 301 | mutex_unlock(vdev->lock); |
300 | return ret; | 302 | return ret; |
301 | } | 303 | } |
@@ -307,11 +309,11 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | |||
307 | 309 | ||
308 | if (!vdev->fops->poll) | 310 | if (!vdev->fops->poll) |
309 | return DEFAULT_POLLMASK; | 311 | return DEFAULT_POLLMASK; |
310 | if (vdev->lock) | 312 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
311 | mutex_lock(vdev->lock); | 313 | mutex_lock(vdev->lock); |
312 | if (video_is_registered(vdev)) | 314 | if (video_is_registered(vdev)) |
313 | ret = vdev->fops->poll(filp, poll); | 315 | ret = vdev->fops->poll(filp, poll); |
314 | if (vdev->lock) | 316 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
315 | mutex_unlock(vdev->lock); | 317 | mutex_unlock(vdev->lock); |
316 | return ret; | 318 | return ret; |
317 | } | 319 | } |
@@ -399,11 +401,12 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
399 | 401 | ||
400 | if (!vdev->fops->mmap) | 402 | if (!vdev->fops->mmap) |
401 | return ret; | 403 | return ret; |
402 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) | 404 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && |
405 | mutex_lock_interruptible(vdev->lock)) | ||
403 | return -ERESTARTSYS; | 406 | return -ERESTARTSYS; |
404 | if (video_is_registered(vdev)) | 407 | if (video_is_registered(vdev)) |
405 | ret = vdev->fops->mmap(filp, vm); | 408 | ret = vdev->fops->mmap(filp, vm); |
406 | if (vdev->lock) | 409 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
407 | mutex_unlock(vdev->lock); | 410 | mutex_unlock(vdev->lock); |
408 | return ret; | 411 | return ret; |
409 | } | 412 | } |
@@ -426,7 +429,8 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
426 | video_get(vdev); | 429 | video_get(vdev); |
427 | mutex_unlock(&videodev_lock); | 430 | mutex_unlock(&videodev_lock); |
428 | if (vdev->fops->open) { | 431 | if (vdev->fops->open) { |
429 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { | 432 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && |
433 | mutex_lock_interruptible(vdev->lock)) { | ||
430 | ret = -ERESTARTSYS; | 434 | ret = -ERESTARTSYS; |
431 | goto err; | 435 | goto err; |
432 | } | 436 | } |
@@ -434,7 +438,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
434 | ret = vdev->fops->open(filp); | 438 | ret = vdev->fops->open(filp); |
435 | else | 439 | else |
436 | ret = -ENODEV; | 440 | ret = -ENODEV; |
437 | if (vdev->lock) | 441 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
438 | mutex_unlock(vdev->lock); | 442 | mutex_unlock(vdev->lock); |
439 | } | 443 | } |
440 | 444 | ||
@@ -452,10 +456,10 @@ static int v4l2_release(struct inode *inode, struct file *filp) | |||
452 | int ret = 0; | 456 | int ret = 0; |
453 | 457 | ||
454 | if (vdev->fops->release) { | 458 | if (vdev->fops->release) { |
455 | if (vdev->lock) | 459 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
456 | mutex_lock(vdev->lock); | 460 | mutex_lock(vdev->lock); |
457 | vdev->fops->release(filp); | 461 | vdev->fops->release(filp); |
458 | if (vdev->lock) | 462 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
459 | mutex_unlock(vdev->lock); | 463 | mutex_unlock(vdev->lock); |
460 | } | 464 | } |
461 | /* decrease the refcount unconditionally since the release() | 465 | /* decrease the refcount unconditionally since the release() |
@@ -831,6 +835,10 @@ int __video_register_device(struct video_device *vdev, int type, int nr, | |||
831 | WARN_ON(video_device[vdev->minor] != NULL); | 835 | WARN_ON(video_device[vdev->minor] != NULL); |
832 | vdev->index = get_index(vdev); | 836 | vdev->index = get_index(vdev); |
833 | mutex_unlock(&videodev_lock); | 837 | mutex_unlock(&videodev_lock); |
838 | /* if no lock was passed, then make sure the LOCK_ALL_FOPS bit is | ||
839 | clear and warn if it wasn't. */ | ||
840 | if (vdev->lock == NULL) | ||
841 | WARN_ON(test_and_clear_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)); | ||
834 | 842 | ||
835 | if (vdev->ioctl_ops) | 843 | if (vdev->ioctl_ops) |
836 | determine_valid_ioctls(vdev); | 844 | determine_valid_ioctls(vdev); |