diff options
-rw-r--r-- | Documentation/video4linux/CARDLIST.bttv | 1 | ||||
-rw-r--r-- | Documentation/video4linux/v4l2-framework.txt | 11 | ||||
-rw-r--r-- | drivers/media/video/v4l2-device.c | 15 | ||||
-rw-r--r-- | include/media/v4l2-device.h | 6 |
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 @@ | |||
157 | 156 -> IVCE-8784 [0000:f050,0001:f050,0002:f050,0003:f050] | 157 | 156 -> IVCE-8784 [0000:f050,0001:f050,0002:f050,0003:f050] |
158 | 157 -> Geovision GV-800(S) (master) [800a:763d] | 158 | 157 -> Geovision GV-800(S) (master) [800a:763d] |
159 | 158 -> Geovision GV-800(S) (slave) [800b:763d,800c:763d,800d:763d] | 159 | 158 -> Geovision GV-800(S) (slave) [800b:763d,800c:763d,800d:763d] |
160 | 159 -> 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 | ||
106 | Unregistering will also automatically unregister all subdevs from the device. | 106 | Unregistering will also automatically unregister all subdevs from the device. |
107 | 107 | ||
108 | If you have a hotpluggable device (e.g. a USB device), then when a disconnect | ||
109 | happens the parent device becomes invalid. Since v4l2_device has a pointer to | ||
110 | that parent device it has to be cleared as well to mark that the parent is | ||
111 | gone. To do this call: | ||
112 | |||
113 | v4l2_device_disconnect(struct v4l2_device *v4l2_dev); | ||
114 | |||
115 | This does *not* unregister the subdevs, so you still need to call the | ||
116 | v4l2_device_unregister() function for that. If your driver is not hotpluggable, | ||
117 | then there is no need to call v4l2_device_disconnect(). | ||
118 | |||
108 | Sometimes you need to iterate over all devices registered by a specific | 119 | Sometimes you need to iterate over all devices registered by a specific |
109 | driver. This is usually the case if multiple device drivers use the same | 120 | driver. This is usually the case if multiple device drivers use the same |
110 | hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv | 121 | hardware. 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 | } |
50 | EXPORT_SYMBOL_GPL(v4l2_device_register); | 50 | EXPORT_SYMBOL_GPL(v4l2_device_register); |
51 | 51 | ||
52 | void 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 | } | ||
59 | EXPORT_SYMBOL_GPL(v4l2_device_disconnect); | ||
60 | |||
52 | void v4l2_device_unregister(struct v4l2_device *v4l2_dev) | 61 | void 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 | } |
66 | EXPORT_SYMBOL_GPL(v4l2_device_unregister); | 73 | EXPORT_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. */ |
55 | int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); | 55 | int __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. */ | ||
59 | void v4l2_device_disconnect(struct v4l2_device *v4l2_dev); | ||
60 | /* Unregister all sub-devices and any other resources related to v4l2_dev. */ | ||
57 | void v4l2_device_unregister(struct v4l2_device *v4l2_dev); | 61 | void 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 |