aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-03-14 07:28:45 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:22 -0400
commitae6cfaace120f4330715b56265ce0e4a710e1276 (patch)
treeed01c11218132e92ce8fe4872fe26c572c3c8842
parent6273fda6e32e2cd9a478545d0cbc15ac497b1f4b (diff)
V4L/DVB (11044): v4l2-device: add v4l2_device_disconnect
Call v4l2_device_disconnect when the parent of a hotpluggable device disconnects. This ensures that you do not have a pointer to a device that is no longer present. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--Documentation/video4linux/CARDLIST.bttv1
-rw-r--r--Documentation/video4linux/v4l2-framework.txt11
-rw-r--r--drivers/media/video/v4l2-device.c15
-rw-r--r--include/media/v4l2-device.h6
4 files changed, 27 insertions, 6 deletions
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index f11c583295e9..e17750473e08 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -157,4 +157,3 @@
157156 -> IVCE-8784 [0000:f050,0001:f050,0002:f050,0003:f050] 157156 -> IVCE-8784 [0000:f050,0001:f050,0002:f050,0003:f050]
158157 -> Geovision GV-800(S) (master) [800a:763d] 158157 -> Geovision GV-800(S) (master) [800a:763d]
159158 -> Geovision GV-800(S) (slave) [800b:763d,800c:763d,800d:763d] 159158 -> Geovision GV-800(S) (slave) [800b:763d,800c:763d,800d:763d]
160159 -> ProVideo PV183 [1830:1540,1831:1540,1832:1540,1833:1540,1834:1540,1835:1540,1836:1540,1837:1540]
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 4207590b2ac8..a31177390e55 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -105,6 +105,17 @@ You unregister with:
105 105
106Unregistering will also automatically unregister all subdevs from the device. 106Unregistering will also automatically unregister all subdevs from the device.
107 107
108If you have a hotpluggable device (e.g. a USB device), then when a disconnect
109happens the parent device becomes invalid. Since v4l2_device has a pointer to
110that parent device it has to be cleared as well to mark that the parent is
111gone. To do this call:
112
113 v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
114
115This does *not* unregister the subdevs, so you still need to call the
116v4l2_device_unregister() function for that. If your driver is not hotpluggable,
117then there is no need to call v4l2_device_disconnect().
118
108Sometimes you need to iterate over all devices registered by a specific 119Sometimes you need to iterate over all devices registered by a specific
109driver. This is usually the case if multiple device drivers use the same 120driver. This is usually the case if multiple device drivers use the same
110hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv 121hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index b3dcb8454379..94aa485ade52 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -49,19 +49,26 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
49} 49}
50EXPORT_SYMBOL_GPL(v4l2_device_register); 50EXPORT_SYMBOL_GPL(v4l2_device_register);
51 51
52void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
53{
54 if (v4l2_dev->dev) {
55 dev_set_drvdata(v4l2_dev->dev, NULL);
56 v4l2_dev->dev = NULL;
57 }
58}
59EXPORT_SYMBOL_GPL(v4l2_device_disconnect);
60
52void v4l2_device_unregister(struct v4l2_device *v4l2_dev) 61void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
53{ 62{
54 struct v4l2_subdev *sd, *next; 63 struct v4l2_subdev *sd, *next;
55 64
56 if (v4l2_dev == NULL) 65 if (v4l2_dev == NULL)
57 return; 66 return;
58 if (v4l2_dev->dev) 67 v4l2_device_disconnect(v4l2_dev);
59 dev_set_drvdata(v4l2_dev->dev, NULL); 68
60 /* Unregister subdevs */ 69 /* Unregister subdevs */
61 list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) 70 list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list)
62 v4l2_device_unregister_subdev(sd); 71 v4l2_device_unregister_subdev(sd);
63
64 v4l2_dev->dev = NULL;
65} 72}
66EXPORT_SYMBOL_GPL(v4l2_device_unregister); 73EXPORT_SYMBOL_GPL(v4l2_device_unregister);
67 74
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 3d8e96f6ceb3..0dd3e8e8653e 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -53,7 +53,11 @@ struct v4l2_device {
53 dev may be NULL in rare cases (ISA devices). In that case you 53 dev may be NULL in rare cases (ISA devices). In that case you
54 must fill in the v4l2_dev->name field before calling this function. */ 54 must fill in the v4l2_dev->name field before calling this function. */
55int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); 55int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
56/* Set v4l2_dev->dev->driver_data to NULL and unregister all sub-devices */ 56/* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects.
57 Since the parent disappears this ensures that v4l2_dev doesn't have an
58 invalid parent pointer. */
59void v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
60/* Unregister all sub-devices and any other resources related to v4l2_dev. */
57void v4l2_device_unregister(struct v4l2_device *v4l2_dev); 61void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
58 62
59/* Register a subdev with a v4l2 device. While registered the subdev module 63/* Register a subdev with a v4l2 device. While registered the subdev module