aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l2-dev.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2009-12-09 06:40:10 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-22 03:53:19 -0400
commit2c0ab67be1b4197a4effac89bb0604832e38be8d (patch)
tree033b1d2c6ae25e05f1f46f3c2e7bdb504c359ad3 /drivers/media/video/v4l2-dev.c
parent95db3a60e0652a52df145aacade1a88c5acef659 (diff)
[media] v4l: Make video_device inherit from media_entity
V4L2 devices are media entities. As such they need to inherit from (include) the media_entity structure. When registering/unregistering the device, the media entity is automatically registered/unregistered. The entity is acquired on device open and released on device close. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/v4l2-dev.c')
-rw-r--r--drivers/media/video/v4l2-dev.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index abe04ef38066..e405b8094b94 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -303,6 +303,9 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
303static int v4l2_open(struct inode *inode, struct file *filp) 303static int v4l2_open(struct inode *inode, struct file *filp)
304{ 304{
305 struct video_device *vdev; 305 struct video_device *vdev;
306#if defined(CONFIG_MEDIA_CONTROLLER)
307 struct media_entity *entity = NULL;
308#endif
306 int ret = 0; 309 int ret = 0;
307 310
308 /* Check if the video device is available */ 311 /* Check if the video device is available */
@@ -316,6 +319,16 @@ static int v4l2_open(struct inode *inode, struct file *filp)
316 /* and increase the device refcount */ 319 /* and increase the device refcount */
317 video_get(vdev); 320 video_get(vdev);
318 mutex_unlock(&videodev_lock); 321 mutex_unlock(&videodev_lock);
322#if defined(CONFIG_MEDIA_CONTROLLER)
323 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {
324 entity = media_entity_get(&vdev->entity);
325 if (!entity) {
326 ret = -EBUSY;
327 video_put(vdev);
328 return ret;
329 }
330 }
331#endif
319 if (vdev->fops->open) { 332 if (vdev->fops->open) {
320 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { 333 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
321 ret = -ERESTARTSYS; 334 ret = -ERESTARTSYS;
@@ -331,8 +344,13 @@ static int v4l2_open(struct inode *inode, struct file *filp)
331 344
332err: 345err:
333 /* decrease the refcount in case of an error */ 346 /* decrease the refcount in case of an error */
334 if (ret) 347 if (ret) {
348#if defined(CONFIG_MEDIA_CONTROLLER)
349 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
350 media_entity_put(entity);
351#endif
335 video_put(vdev); 352 video_put(vdev);
353 }
336 return ret; 354 return ret;
337} 355}
338 356
@@ -349,7 +367,10 @@ static int v4l2_release(struct inode *inode, struct file *filp)
349 if (vdev->lock) 367 if (vdev->lock)
350 mutex_unlock(vdev->lock); 368 mutex_unlock(vdev->lock);
351 } 369 }
352 370#if defined(CONFIG_MEDIA_CONTROLLER)
371 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
372 media_entity_put(&vdev->entity);
373#endif
353 /* decrease the refcount unconditionally since the release() 374 /* decrease the refcount unconditionally since the release()
354 return value is ignored. */ 375 return value is ignored. */
355 video_put(vdev); 376 video_put(vdev);
@@ -585,12 +606,27 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
585 if (nr != -1 && nr != vdev->num && warn_if_nr_in_use) 606 if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
586 printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__, 607 printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__,
587 name_base, nr, video_device_node_name(vdev)); 608 name_base, nr, video_device_node_name(vdev));
588 609#if defined(CONFIG_MEDIA_CONTROLLER)
589 /* Part 5: Activate this minor. The char device can now be used. */ 610 /* Part 5: Register the entity. */
611 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {
612 vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
613 vdev->entity.name = vdev->name;
614 vdev->entity.v4l.major = VIDEO_MAJOR;
615 vdev->entity.v4l.minor = vdev->minor;
616 ret = media_device_register_entity(vdev->v4l2_dev->mdev,
617 &vdev->entity);
618 if (ret < 0)
619 printk(KERN_WARNING
620 "%s: media_device_register_entity failed\n",
621 __func__);
622 }
623#endif
624 /* Part 6: Activate this minor. The char device can now be used. */
590 set_bit(V4L2_FL_REGISTERED, &vdev->flags); 625 set_bit(V4L2_FL_REGISTERED, &vdev->flags);
591 mutex_lock(&videodev_lock); 626 mutex_lock(&videodev_lock);
592 video_device[vdev->minor] = vdev; 627 video_device[vdev->minor] = vdev;
593 mutex_unlock(&videodev_lock); 628 mutex_unlock(&videodev_lock);
629
594 return 0; 630 return 0;
595 631
596cleanup: 632cleanup:
@@ -618,6 +654,11 @@ void video_unregister_device(struct video_device *vdev)
618 if (!vdev || !video_is_registered(vdev)) 654 if (!vdev || !video_is_registered(vdev))
619 return; 655 return;
620 656
657#if defined(CONFIG_MEDIA_CONTROLLER)
658 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
659 media_device_unregister_entity(&vdev->entity);
660#endif
661
621 mutex_lock(&videodev_lock); 662 mutex_lock(&videodev_lock);
622 /* This must be in a critical section to prevent a race with v4l2_open. 663 /* This must be in a critical section to prevent a race with v4l2_open.
623 * Once this bit has been cleared video_get may never be called again. 664 * Once this bit has been cleared video_get may never be called again.