diff options
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/media/0019-v4l-Make-v4l2_subdev-inherit-from-media_entity.patch')
-rw-r--r-- | extras/recipes-kernel/linux/linux-omap/media/0019-v4l-Make-v4l2_subdev-inherit-from-media_entity.patch | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/media/0019-v4l-Make-v4l2_subdev-inherit-from-media_entity.patch b/extras/recipes-kernel/linux/linux-omap/media/0019-v4l-Make-v4l2_subdev-inherit-from-media_entity.patch new file mode 100644 index 00000000..c7ae882a --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/media/0019-v4l-Make-v4l2_subdev-inherit-from-media_entity.patch | |||
@@ -0,0 +1,265 @@ | |||
1 | From ab4bf9e43078f79ba2b287e6dd6d6871901d0341 Mon Sep 17 00:00:00 2001 | ||
2 | From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
3 | Date: Wed, 9 Dec 2009 12:40:08 +0100 | ||
4 | Subject: [PATCH 19/43] v4l: Make v4l2_subdev inherit from media_entity | ||
5 | |||
6 | V4L2 subdevices are media entities. As such they need to inherit from | ||
7 | (include) the media_entity structure. | ||
8 | |||
9 | When registering/unregistering the subdevice, the media entity is | ||
10 | automatically registered/unregistered. The entity is acquired on device | ||
11 | open and released on device close. | ||
12 | |||
13 | Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
14 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
15 | --- | ||
16 | Documentation/video4linux/v4l2-framework.txt | 23 ++++++++++++++ | ||
17 | drivers/media/video/v4l2-device.c | 39 ++++++++++++++++++++---- | ||
18 | drivers/media/video/v4l2-subdev.c | 41 ++++++++++++++++++++++++- | ||
19 | include/media/v4l2-subdev.h | 10 ++++++ | ||
20 | 4 files changed, 104 insertions(+), 9 deletions(-) | ||
21 | |||
22 | diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt | ||
23 | index f231bc2..d0fb880 100644 | ||
24 | --- a/Documentation/video4linux/v4l2-framework.txt | ||
25 | +++ b/Documentation/video4linux/v4l2-framework.txt | ||
26 | @@ -268,6 +268,26 @@ A sub-device driver initializes the v4l2_subdev struct using: | ||
27 | Afterwards you need to initialize subdev->name with a unique name and set the | ||
28 | module owner. This is done for you if you use the i2c helper functions. | ||
29 | |||
30 | +If integration with the media framework is needed, you must initialize the | ||
31 | +media_entity struct embedded in the v4l2_subdev struct (entity field) by | ||
32 | +calling media_entity_init(): | ||
33 | + | ||
34 | + struct media_pad *pads = &my_sd->pads; | ||
35 | + int err; | ||
36 | + | ||
37 | + err = media_entity_init(&sd->entity, npads, pads, 0); | ||
38 | + | ||
39 | +The pads array must have been previously initialized. There is no need to | ||
40 | +manually set the struct media_entity type and name fields, but the revision | ||
41 | +field must be initialized if needed. | ||
42 | + | ||
43 | +A reference to the entity will be automatically acquired/released when the | ||
44 | +subdev device node (if any) is opened/closed. | ||
45 | + | ||
46 | +Don't forget to cleanup the media entity before the sub-device is destroyed: | ||
47 | + | ||
48 | + media_entity_cleanup(&sd->entity); | ||
49 | + | ||
50 | A device (bridge) driver needs to register the v4l2_subdev with the | ||
51 | v4l2_device: | ||
52 | |||
53 | @@ -277,6 +297,9 @@ This can fail if the subdev module disappeared before it could be registered. | ||
54 | After this function was called successfully the subdev->dev field points to | ||
55 | the v4l2_device. | ||
56 | |||
57 | +If the v4l2_device parent device has a non-NULL mdev field, the sub-device | ||
58 | +entity will be automatically registered with the media device. | ||
59 | + | ||
60 | You can unregister a sub-device using: | ||
61 | |||
62 | v4l2_device_unregister_subdev(sd); | ||
63 | diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c | ||
64 | index 5c16a12..69cb429 100644 | ||
65 | --- a/drivers/media/video/v4l2-device.c | ||
66 | +++ b/drivers/media/video/v4l2-device.c | ||
67 | @@ -116,8 +116,11 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) | ||
68 | EXPORT_SYMBOL_GPL(v4l2_device_unregister); | ||
69 | |||
70 | int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, | ||
71 | - struct v4l2_subdev *sd) | ||
72 | + struct v4l2_subdev *sd) | ||
73 | { | ||
74 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
75 | + struct media_entity *entity = &sd->entity; | ||
76 | +#endif | ||
77 | struct video_device *vdev; | ||
78 | int err; | ||
79 | |||
80 | @@ -135,7 +138,16 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, | ||
81 | err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler); | ||
82 | if (err) | ||
83 | return err; | ||
84 | - | ||
85 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
86 | + /* Register the entity. */ | ||
87 | + if (v4l2_dev->mdev) { | ||
88 | + err = media_device_register_entity(v4l2_dev->mdev, entity); | ||
89 | + if (err < 0) { | ||
90 | + module_put(sd->owner); | ||
91 | + return err; | ||
92 | + } | ||
93 | + } | ||
94 | +#endif | ||
95 | sd->v4l2_dev = v4l2_dev; | ||
96 | spin_lock(&v4l2_dev->lock); | ||
97 | list_add_tail(&sd->list, &v4l2_dev->subdevs); | ||
98 | @@ -150,26 +162,39 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, | ||
99 | if (sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE) { | ||
100 | err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1, | ||
101 | sd->owner); | ||
102 | - if (err < 0) | ||
103 | + if (err < 0) { | ||
104 | v4l2_device_unregister_subdev(sd); | ||
105 | + return err; | ||
106 | + } | ||
107 | } | ||
108 | - | ||
109 | - return err; | ||
110 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
111 | + entity->v4l.major = VIDEO_MAJOR; | ||
112 | + entity->v4l.minor = vdev->minor; | ||
113 | +#endif | ||
114 | + return 0; | ||
115 | } | ||
116 | EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); | ||
117 | |||
118 | void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) | ||
119 | { | ||
120 | + struct v4l2_device *v4l2_dev; | ||
121 | + | ||
122 | /* return if it isn't registered */ | ||
123 | if (sd == NULL || sd->v4l2_dev == NULL) | ||
124 | return; | ||
125 | |||
126 | - spin_lock(&sd->v4l2_dev->lock); | ||
127 | + v4l2_dev = sd->v4l2_dev; | ||
128 | + | ||
129 | + spin_lock(&v4l2_dev->lock); | ||
130 | list_del(&sd->list); | ||
131 | - spin_unlock(&sd->v4l2_dev->lock); | ||
132 | + spin_unlock(&v4l2_dev->lock); | ||
133 | sd->v4l2_dev = NULL; | ||
134 | |||
135 | module_put(sd->owner); | ||
136 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
137 | + if (v4l2_dev->mdev) | ||
138 | + media_device_unregister_entity(&sd->entity); | ||
139 | +#endif | ||
140 | video_unregister_device(&sd->devnode); | ||
141 | } | ||
142 | EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); | ||
143 | diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c | ||
144 | index fbccefd..a49856a 100644 | ||
145 | --- a/drivers/media/video/v4l2-subdev.c | ||
146 | +++ b/drivers/media/video/v4l2-subdev.c | ||
147 | @@ -35,7 +35,10 @@ static int subdev_open(struct file *file) | ||
148 | { | ||
149 | struct video_device *vdev = video_devdata(file); | ||
150 | struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); | ||
151 | - struct v4l2_fh *vfh; | ||
152 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
153 | + struct media_entity *entity; | ||
154 | +#endif | ||
155 | + struct v4l2_fh *vfh = NULL; | ||
156 | int ret; | ||
157 | |||
158 | if (!sd->initialized) | ||
159 | @@ -61,11 +64,20 @@ static int subdev_open(struct file *file) | ||
160 | v4l2_fh_add(vfh); | ||
161 | file->private_data = vfh; | ||
162 | } | ||
163 | - | ||
164 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
165 | + if (sd->v4l2_dev->mdev) { | ||
166 | + entity = media_entity_get(&sd->entity); | ||
167 | + if (!entity) { | ||
168 | + ret = -EBUSY; | ||
169 | + goto err; | ||
170 | + } | ||
171 | + } | ||
172 | +#endif | ||
173 | return 0; | ||
174 | |||
175 | err: | ||
176 | if (vfh != NULL) { | ||
177 | + v4l2_fh_del(vfh); | ||
178 | v4l2_fh_exit(vfh); | ||
179 | kfree(vfh); | ||
180 | } | ||
181 | @@ -75,8 +87,16 @@ err: | ||
182 | |||
183 | static int subdev_close(struct file *file) | ||
184 | { | ||
185 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
186 | + struct video_device *vdev = video_devdata(file); | ||
187 | + struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); | ||
188 | +#endif | ||
189 | struct v4l2_fh *vfh = file->private_data; | ||
190 | |||
191 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
192 | + if (sd->v4l2_dev->mdev) | ||
193 | + media_entity_put(&sd->entity); | ||
194 | +#endif | ||
195 | if (vfh != NULL) { | ||
196 | v4l2_fh_del(vfh); | ||
197 | v4l2_fh_exit(vfh); | ||
198 | @@ -176,5 +196,22 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) | ||
199 | sd->dev_priv = NULL; | ||
200 | sd->host_priv = NULL; | ||
201 | sd->initialized = 1; | ||
202 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
203 | + sd->entity.name = sd->name; | ||
204 | + sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; | ||
205 | +#endif | ||
206 | } | ||
207 | EXPORT_SYMBOL(v4l2_subdev_init); | ||
208 | + | ||
209 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
210 | +int v4l2_subdev_set_power(struct media_entity *entity, int power) | ||
211 | +{ | ||
212 | + struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); | ||
213 | + | ||
214 | + dev_dbg(entity->parent->dev, | ||
215 | + "%s power%s\n", entity->name, power ? "on" : "off"); | ||
216 | + | ||
217 | + return v4l2_subdev_call(sd, core, s_power, power); | ||
218 | +} | ||
219 | +EXPORT_SYMBOL_GPL(v4l2_subdev_set_power); | ||
220 | +#endif | ||
221 | diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h | ||
222 | index 68cbe48..7d55b0c 100644 | ||
223 | --- a/include/media/v4l2-subdev.h | ||
224 | +++ b/include/media/v4l2-subdev.h | ||
225 | @@ -21,6 +21,7 @@ | ||
226 | #ifndef _V4L2_SUBDEV_H | ||
227 | #define _V4L2_SUBDEV_H | ||
228 | |||
229 | +#include <media/media-entity.h> | ||
230 | #include <media/v4l2-common.h> | ||
231 | #include <media/v4l2-dev.h> | ||
232 | #include <media/v4l2-mediabus.h> | ||
233 | @@ -437,6 +438,9 @@ struct v4l2_subdev_ops { | ||
234 | stand-alone or embedded in a larger struct. | ||
235 | */ | ||
236 | struct v4l2_subdev { | ||
237 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
238 | + struct media_entity entity; | ||
239 | +#endif | ||
240 | struct list_head list; | ||
241 | struct module *owner; | ||
242 | u32 flags; | ||
243 | @@ -458,6 +462,8 @@ struct v4l2_subdev { | ||
244 | unsigned int nevents; | ||
245 | }; | ||
246 | |||
247 | +#define media_entity_to_v4l2_subdev(ent) \ | ||
248 | + container_of(ent, struct v4l2_subdev, entity) | ||
249 | #define vdev_to_v4l2_subdev(vdev) \ | ||
250 | container_of(vdev, struct v4l2_subdev, devnode) | ||
251 | |||
252 | @@ -486,6 +492,10 @@ static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd) | ||
253 | void v4l2_subdev_init(struct v4l2_subdev *sd, | ||
254 | const struct v4l2_subdev_ops *ops); | ||
255 | |||
256 | +#if defined(CONFIG_MEDIA_CONTROLLER) | ||
257 | +int v4l2_subdev_set_power(struct media_entity *entity, int power); | ||
258 | +#endif | ||
259 | + | ||
260 | /* Call an ops of a v4l2_subdev, doing the right checks against | ||
261 | NULL pointers. | ||
262 | |||
263 | -- | ||
264 | 1.6.6.1 | ||
265 | |||