summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l2-dev.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2011-03-12 10:37:19 +0100
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-22 20:38:05 +0100
commitbedf8bcf6b4f90a6e31add3721a2e71877289381 (patch)
tree855560191d12dc9f21db59fca801c67f036b5167 /drivers/media/video/v4l2-dev.c
parent[media] cx18: use core priority handling (diff)
downloadlinux-bedf8bcf6b4f90a6e31add3721a2e71877289381.tar.xz
linux-bedf8bcf6b4f90a6e31add3721a2e71877289381.zip
[media] v4l2-device: add kref and a release function
The video_device struct has proper ref counting and its release function will be called when the last user releases it. But no such support was available for struct v4l2_device. This made it hard to determine when a USB driver can release the device if it has multiple device nodes. With one device node it is easy of course, since when the device node is released, the whole device can be released. This patch adds refcounting to v4l2_device. When registering device nodes the v4l2_device refcount will be increased, when releasing device nodes it will be decreased. The (optional) release function will be called when the last device node was released. Signed-off-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.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 6b1ef85d8cc8..1898099ec65a 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -143,6 +143,7 @@ static inline void video_put(struct video_device *vdev)
static void v4l2_device_release(struct device *cd)
{
struct video_device *vdev = to_video_device(cd);
+ struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
mutex_lock(&videodev_lock);
if (video_device[vdev->minor] != vdev) {
@@ -169,6 +170,10 @@ static void v4l2_device_release(struct device *cd)
/* Release video_device and perform other
cleanups as needed. */
vdev->release(vdev);
+
+ /* Decrease v4l2_device refcount */
+ if (v4l2_dev)
+ v4l2_device_put(v4l2_dev);
}
static struct class video_class = {
@@ -676,6 +681,11 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__,
name_base, nr, video_device_node_name(vdev));
+
+ /* Increase v4l2_device refcount */
+ if (vdev->v4l2_dev)
+ v4l2_device_get(vdev->v4l2_dev);
+
#if defined(CONFIG_MEDIA_CONTROLLER)
/* Part 5: Register the entity. */
if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {