summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-04-19 12:27:56 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-04-19 17:23:38 -0300
commitee71e7b3ae1780e4475aa5dd980dd99c0309079b (patch)
tree4c15e0fc2f11ebd5fe5dee23575b87f7394566ed
parentaa6d5f29534a6d1459f9768c591a7a72aadc5941 (diff)
[media] V4L: fix incorrect refcounting
Both radio-keene and dsbr100 did one v4l2_device_get too many. Thus the refcount never became 0 and that causes a memory leak. Also updated the V4L2 framework documentation accordingly. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--Documentation/video4linux/v4l2-framework.txt14
-rw-r--r--drivers/media/radio/dsbr100.c1
-rw-r--r--drivers/media/radio/radio-keene.c1
3 files changed, 9 insertions, 7 deletions
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 659b2ba12a4..e3dfc268d9c 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -182,11 +182,11 @@ static int __devinit drv_probe(struct pci_dev *pdev,
}
If you have multiple device nodes then it can be difficult to know when it is
-safe to unregister v4l2_device. For this purpose v4l2_device has refcounting
-support. The refcount is increased whenever video_register_device is called and
-it is decreased whenever that device node is released. When the refcount reaches
-zero, then the v4l2_device release() callback is called. You can do your final
-cleanup there.
+safe to unregister v4l2_device for hotpluggable devices. For this purpose
+v4l2_device has refcounting support. The refcount is increased whenever
+video_register_device is called and it is decreased whenever that device node
+is released. When the refcount reaches zero, then the v4l2_device release()
+callback is called. You can do your final cleanup there.
If other device nodes (e.g. ALSA) are created, then you can increase and
decrease the refcount manually as well by calling:
@@ -197,6 +197,10 @@ or:
int v4l2_device_put(struct v4l2_device *v4l2_dev);
+Since the initial refcount is 1 you also need to call v4l2_device_put in the
+disconnect() callback (for USB devices) or in the remove() callback (for e.g.
+PCI devices), otherwise the refcount will never reach 0.
+
struct v4l2_subdev
------------------
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index f36905b6364..bf813a63ab2 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -481,7 +481,6 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
{
struct dsbr100_device *radio = usb_get_intfdata(intf);
- v4l2_device_get(&radio->v4l2_dev);
mutex_lock(&radio->v4l2_lock);
usb_set_intfdata(intf, NULL);
video_unregister_device(&radio->videodev);
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c
index 26a2b7a0304..5f33047d0d4 100644
--- a/drivers/media/radio/radio-keene.c
+++ b/drivers/media/radio/radio-keene.c
@@ -148,7 +148,6 @@ static void usb_keene_disconnect(struct usb_interface *intf)
{
struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));
- v4l2_device_get(&radio->v4l2_dev);
mutex_lock(&radio->lock);
usb_set_intfdata(intf, NULL);
video_unregister_device(&radio->vdev);