diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2009-12-09 06:40:03 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-22 03:53:16 -0400 |
commit | 97548ed4c4661502cdfd1aabd5d3876fa4f5cc2e (patch) | |
tree | c85b85954f53e3a97b6590de8d5d5396e7c43358 | |
parent | 1651333b09743887bc2dd3d158a11853a2be3fe7 (diff) |
[media] media: Links setup
Create the following ioctl and implement it at the media device level to
setup links.
- MEDIA_IOC_SETUP_LINK: Modify the properties of a given link
The only property that can currently be modified is the ENABLED link
flag to enable/disable a link. Links marked with the IMMUTABLE link flag
can not be enabled or disabled.
Enabling or disabling a link has effects on entities' use count. Those
changes are automatically propagated through the graph.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | Documentation/DocBook/media-entities.tmpl | 2 | ||||
-rw-r--r-- | Documentation/DocBook/v4l/media-controller.xml | 1 | ||||
-rw-r--r-- | Documentation/DocBook/v4l/media-ioc-setup-link.xml | 90 | ||||
-rw-r--r-- | Documentation/media-framework.txt | 42 | ||||
-rw-r--r-- | drivers/media/media-device.c | 45 | ||||
-rw-r--r-- | drivers/media/media-entity.c | 155 | ||||
-rw-r--r-- | include/linux/media.h | 1 | ||||
-rw-r--r-- | include/media/media-device.h | 3 | ||||
-rw-r--r-- | include/media/media-entity.h | 17 |
9 files changed, 356 insertions, 0 deletions
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl index 2bd7b27f8553..121db1549244 100644 --- a/Documentation/DocBook/media-entities.tmpl +++ b/Documentation/DocBook/media-entities.tmpl | |||
@@ -94,6 +94,7 @@ | |||
94 | <!ENTITY MEDIA-IOC-DEVICE-INFO "<link linkend='media-ioc-device-info'><constant>MEDIA_IOC_DEVICE_INFO</constant></link>"> | 94 | <!ENTITY MEDIA-IOC-DEVICE-INFO "<link linkend='media-ioc-device-info'><constant>MEDIA_IOC_DEVICE_INFO</constant></link>"> |
95 | <!ENTITY MEDIA-IOC-ENUM-ENTITIES "<link linkend='media-ioc-enum-entities'><constant>MEDIA_IOC_ENUM_ENTITIES</constant></link>"> | 95 | <!ENTITY MEDIA-IOC-ENUM-ENTITIES "<link linkend='media-ioc-enum-entities'><constant>MEDIA_IOC_ENUM_ENTITIES</constant></link>"> |
96 | <!ENTITY MEDIA-IOC-ENUM-LINKS "<link linkend='media-ioc-enum-links'><constant>MEDIA_IOC_ENUM_LINKS</constant></link>"> | 96 | <!ENTITY MEDIA-IOC-ENUM-LINKS "<link linkend='media-ioc-enum-links'><constant>MEDIA_IOC_ENUM_LINKS</constant></link>"> |
97 | <!ENTITY MEDIA-IOC-SETUP-LINK "<link linkend='media-ioc-setup-link'><constant>MEDIA_IOC_SETUP_LINK</constant></link>"> | ||
97 | 98 | ||
98 | <!-- Types --> | 99 | <!-- Types --> |
99 | <!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>"> | 100 | <!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>"> |
@@ -348,6 +349,7 @@ | |||
348 | <!ENTITY sub-media-ioc-device-info SYSTEM "v4l/media-ioc-device-info.xml"> | 349 | <!ENTITY sub-media-ioc-device-info SYSTEM "v4l/media-ioc-device-info.xml"> |
349 | <!ENTITY sub-media-ioc-enum-entities SYSTEM "v4l/media-ioc-enum-entities.xml"> | 350 | <!ENTITY sub-media-ioc-enum-entities SYSTEM "v4l/media-ioc-enum-entities.xml"> |
350 | <!ENTITY sub-media-ioc-enum-links SYSTEM "v4l/media-ioc-enum-links.xml"> | 351 | <!ENTITY sub-media-ioc-enum-links SYSTEM "v4l/media-ioc-enum-links.xml"> |
352 | <!ENTITY sub-media-ioc-setup-link SYSTEM "v4l/media-ioc-setup-link.xml"> | ||
351 | 353 | ||
352 | <!-- Function Reference --> | 354 | <!-- Function Reference --> |
353 | <!ENTITY close SYSTEM "v4l/func-close.xml"> | 355 | <!ENTITY close SYSTEM "v4l/func-close.xml"> |
diff --git a/Documentation/DocBook/v4l/media-controller.xml b/Documentation/DocBook/v4l/media-controller.xml index 2c4fd2b27683..2dc25e1d4089 100644 --- a/Documentation/DocBook/v4l/media-controller.xml +++ b/Documentation/DocBook/v4l/media-controller.xml | |||
@@ -85,4 +85,5 @@ | |||
85 | &sub-media-ioc-device-info; | 85 | &sub-media-ioc-device-info; |
86 | &sub-media-ioc-enum-entities; | 86 | &sub-media-ioc-enum-entities; |
87 | &sub-media-ioc-enum-links; | 87 | &sub-media-ioc-enum-links; |
88 | &sub-media-ioc-setup-link; | ||
88 | </appendix> | 89 | </appendix> |
diff --git a/Documentation/DocBook/v4l/media-ioc-setup-link.xml b/Documentation/DocBook/v4l/media-ioc-setup-link.xml new file mode 100644 index 000000000000..09ab3d2b3a52 --- /dev/null +++ b/Documentation/DocBook/v4l/media-ioc-setup-link.xml | |||
@@ -0,0 +1,90 @@ | |||
1 | <refentry id="media-ioc-setup-link"> | ||
2 | <refmeta> | ||
3 | <refentrytitle>ioctl MEDIA_IOC_SETUP_LINK</refentrytitle> | ||
4 | &manvol; | ||
5 | </refmeta> | ||
6 | |||
7 | <refnamediv> | ||
8 | <refname>MEDIA_IOC_SETUP_LINK</refname> | ||
9 | <refpurpose>Modify the properties of a link</refpurpose> | ||
10 | </refnamediv> | ||
11 | |||
12 | <refsynopsisdiv> | ||
13 | <funcsynopsis> | ||
14 | <funcprototype> | ||
15 | <funcdef>int <function>ioctl</function></funcdef> | ||
16 | <paramdef>int <parameter>fd</parameter></paramdef> | ||
17 | <paramdef>int <parameter>request</parameter></paramdef> | ||
18 | <paramdef>struct media_link_desc *<parameter>argp</parameter></paramdef> | ||
19 | </funcprototype> | ||
20 | </funcsynopsis> | ||
21 | </refsynopsisdiv> | ||
22 | |||
23 | <refsect1> | ||
24 | <title>Arguments</title> | ||
25 | |||
26 | <variablelist> | ||
27 | <varlistentry> | ||
28 | <term><parameter>fd</parameter></term> | ||
29 | <listitem> | ||
30 | <para>File descriptor returned by | ||
31 | <link linkend='media-func-open'><function>open()</function></link>.</para> | ||
32 | </listitem> | ||
33 | </varlistentry> | ||
34 | <varlistentry> | ||
35 | <term><parameter>request</parameter></term> | ||
36 | <listitem> | ||
37 | <para>MEDIA_IOC_ENUM_LINKS</para> | ||
38 | </listitem> | ||
39 | </varlistentry> | ||
40 | <varlistentry> | ||
41 | <term><parameter>argp</parameter></term> | ||
42 | <listitem> | ||
43 | <para></para> | ||
44 | </listitem> | ||
45 | </varlistentry> | ||
46 | </variablelist> | ||
47 | </refsect1> | ||
48 | |||
49 | <refsect1> | ||
50 | <title>Description</title> | ||
51 | |||
52 | <para>To change link properties applications fill a &media-link-desc; with | ||
53 | link identification information (source and sink pad) and the new requested | ||
54 | link flags. They then call the MEDIA_IOC_SETUP_LINK ioctl with a pointer to | ||
55 | that structure.</para> | ||
56 | <para>The only configurable property is the <constant>ENABLED</constant> | ||
57 | link flag to enable/disable a link. Links marked with the | ||
58 | <constant>IMMUTABLE</constant> link flag can not be enabled or disabled. | ||
59 | </para> | ||
60 | <para>Link configuration has no side effect on other links. If an enabled | ||
61 | link at the sink pad prevents the link from being enabled, the driver | ||
62 | returns with an &EBUSY;.</para> | ||
63 | <para>If the specified link can't be found the driver returns with an | ||
64 | &EINVAL;.</para> | ||
65 | </refsect1> | ||
66 | |||
67 | <refsect1> | ||
68 | &return-value; | ||
69 | |||
70 | <variablelist> | ||
71 | <varlistentry> | ||
72 | <term><errorcode>EBUSY</errorcode></term> | ||
73 | <listitem> | ||
74 | <para>The link properties can't be changed because the link is | ||
75 | currently busy. This can be caused, for instance, by an active media | ||
76 | stream (audio or video) on the link. The ioctl shouldn't be retried if | ||
77 | no other action is performed before to fix the problem.</para> | ||
78 | </listitem> | ||
79 | </varlistentry> | ||
80 | <varlistentry> | ||
81 | <term><errorcode>EINVAL</errorcode></term> | ||
82 | <listitem> | ||
83 | <para>The &media-link-desc; references a non-existing link, or the | ||
84 | link is immutable and an attempt to modify its configuration was made. | ||
85 | </para> | ||
86 | </listitem> | ||
87 | </varlistentry> | ||
88 | </variablelist> | ||
89 | </refsect1> | ||
90 | </refentry> | ||
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt index 78ae02095372..4809221c0ff9 100644 --- a/Documentation/media-framework.txt +++ b/Documentation/media-framework.txt | |||
@@ -259,6 +259,16 @@ When the graph traversal is complete the function will return NULL. | |||
259 | Graph traversal can be interrupted at any moment. No cleanup function call is | 259 | Graph traversal can be interrupted at any moment. No cleanup function call is |
260 | required and the graph structure can be freed normally. | 260 | required and the graph structure can be freed normally. |
261 | 261 | ||
262 | Helper functions can be used to find a link between two given pads, or a pad | ||
263 | connected to another pad through an enabled link | ||
264 | |||
265 | media_entity_find_link(struct media_pad *source, | ||
266 | struct media_pad *sink); | ||
267 | |||
268 | media_entity_remote_source(struct media_pad *pad); | ||
269 | |||
270 | Refer to the kerneldoc documentation for more information. | ||
271 | |||
262 | 272 | ||
263 | Use count and power handling | 273 | Use count and power handling |
264 | ---------------------------- | 274 | ---------------------------- |
@@ -271,3 +281,35 @@ track the number of users of every entity for power management needs. | |||
271 | The use_count field is owned by media drivers and must not be touched by entity | 281 | The use_count field is owned by media drivers and must not be touched by entity |
272 | drivers. Access to the field must be protected by the media device graph_mutex | 282 | drivers. Access to the field must be protected by the media device graph_mutex |
273 | lock. | 283 | lock. |
284 | |||
285 | |||
286 | Links setup | ||
287 | ----------- | ||
288 | |||
289 | Link properties can be modified at runtime by calling | ||
290 | |||
291 | media_entity_setup_link(struct media_link *link, u32 flags); | ||
292 | |||
293 | The flags argument contains the requested new link flags. | ||
294 | |||
295 | The only configurable property is the ENABLED link flag to enable/disable a | ||
296 | link. Links marked with the IMMUTABLE link flag can not be enabled or disabled. | ||
297 | |||
298 | When a link is enabled or disabled, the media framework calls the | ||
299 | link_setup operation for the two entities at the source and sink of the link, | ||
300 | in that order. If the second link_setup call fails, another link_setup call is | ||
301 | made on the first entity to restore the original link flags. | ||
302 | |||
303 | Media device drivers can be notified of link setup operations by setting the | ||
304 | media_device::link_notify pointer to a callback function. If provided, the | ||
305 | notification callback will be called before enabling and after disabling | ||
306 | links. | ||
307 | |||
308 | Entity drivers must implement the link_setup operation if any of their links | ||
309 | is non-immutable. The operation must either configure the hardware or store | ||
310 | the configuration information to be applied later. | ||
311 | |||
312 | Link configuration must not have any side effect on other links. If an enabled | ||
313 | link at a sink pad prevents another link at the same pad from being disabled, | ||
314 | the link_setup operation must return -EBUSY and can't implicitly disable the | ||
315 | first enabled link. | ||
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 648a9d892ac1..16b70b4412f7 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c | |||
@@ -172,6 +172,44 @@ static long media_device_enum_links(struct media_device *mdev, | |||
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
174 | 174 | ||
175 | static long media_device_setup_link(struct media_device *mdev, | ||
176 | struct media_link_desc __user *_ulink) | ||
177 | { | ||
178 | struct media_link *link = NULL; | ||
179 | struct media_link_desc ulink; | ||
180 | struct media_entity *source; | ||
181 | struct media_entity *sink; | ||
182 | int ret; | ||
183 | |||
184 | if (copy_from_user(&ulink, _ulink, sizeof(ulink))) | ||
185 | return -EFAULT; | ||
186 | |||
187 | /* Find the source and sink entities and link. | ||
188 | */ | ||
189 | source = find_entity(mdev, ulink.source.entity); | ||
190 | sink = find_entity(mdev, ulink.sink.entity); | ||
191 | |||
192 | if (source == NULL || sink == NULL) | ||
193 | return -EINVAL; | ||
194 | |||
195 | if (ulink.source.index >= source->num_pads || | ||
196 | ulink.sink.index >= sink->num_pads) | ||
197 | return -EINVAL; | ||
198 | |||
199 | link = media_entity_find_link(&source->pads[ulink.source.index], | ||
200 | &sink->pads[ulink.sink.index]); | ||
201 | if (link == NULL) | ||
202 | return -EINVAL; | ||
203 | |||
204 | /* Setup the link on both entities. */ | ||
205 | ret = __media_entity_setup_link(link, ulink.flags); | ||
206 | |||
207 | if (copy_to_user(_ulink, &ulink, sizeof(ulink))) | ||
208 | return -EFAULT; | ||
209 | |||
210 | return ret; | ||
211 | } | ||
212 | |||
175 | static long media_device_ioctl(struct file *filp, unsigned int cmd, | 213 | static long media_device_ioctl(struct file *filp, unsigned int cmd, |
176 | unsigned long arg) | 214 | unsigned long arg) |
177 | { | 215 | { |
@@ -197,6 +235,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, | |||
197 | mutex_unlock(&dev->graph_mutex); | 235 | mutex_unlock(&dev->graph_mutex); |
198 | break; | 236 | break; |
199 | 237 | ||
238 | case MEDIA_IOC_SETUP_LINK: | ||
239 | mutex_lock(&dev->graph_mutex); | ||
240 | ret = media_device_setup_link(dev, | ||
241 | (struct media_link_desc __user *)arg); | ||
242 | mutex_unlock(&dev->graph_mutex); | ||
243 | break; | ||
244 | |||
200 | default: | 245 | default: |
201 | ret = -ENOIOCTLCMD; | 246 | ret = -ENOIOCTLCMD; |
202 | } | 247 | } |
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 3e7e2d569cec..6795c920d460 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c | |||
@@ -306,3 +306,158 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, | |||
306 | return 0; | 306 | return 0; |
307 | } | 307 | } |
308 | EXPORT_SYMBOL_GPL(media_entity_create_link); | 308 | EXPORT_SYMBOL_GPL(media_entity_create_link); |
309 | |||
310 | static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) | ||
311 | { | ||
312 | const u32 mask = MEDIA_LNK_FL_ENABLED; | ||
313 | int ret; | ||
314 | |||
315 | /* Notify both entities. */ | ||
316 | ret = media_entity_call(link->source->entity, link_setup, | ||
317 | link->source, link->sink, flags); | ||
318 | if (ret < 0 && ret != -ENOIOCTLCMD) | ||
319 | return ret; | ||
320 | |||
321 | ret = media_entity_call(link->sink->entity, link_setup, | ||
322 | link->sink, link->source, flags); | ||
323 | if (ret < 0 && ret != -ENOIOCTLCMD) { | ||
324 | media_entity_call(link->source->entity, link_setup, | ||
325 | link->source, link->sink, link->flags); | ||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | link->flags = (link->flags & ~mask) | (flags & mask); | ||
330 | link->reverse->flags = link->flags; | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * __media_entity_setup_link - Configure a media link | ||
337 | * @link: The link being configured | ||
338 | * @flags: Link configuration flags | ||
339 | * | ||
340 | * The bulk of link setup is handled by the two entities connected through the | ||
341 | * link. This function notifies both entities of the link configuration change. | ||
342 | * | ||
343 | * If the link is immutable or if the current and new configuration are | ||
344 | * identical, return immediately. | ||
345 | * | ||
346 | * The user is expected to hold link->source->parent->mutex. If not, | ||
347 | * media_entity_setup_link() should be used instead. | ||
348 | */ | ||
349 | int __media_entity_setup_link(struct media_link *link, u32 flags) | ||
350 | { | ||
351 | struct media_device *mdev; | ||
352 | struct media_entity *source, *sink; | ||
353 | int ret = -EBUSY; | ||
354 | |||
355 | if (link == NULL) | ||
356 | return -EINVAL; | ||
357 | |||
358 | if (link->flags & MEDIA_LNK_FL_IMMUTABLE) | ||
359 | return link->flags == flags ? 0 : -EINVAL; | ||
360 | |||
361 | if (link->flags == flags) | ||
362 | return 0; | ||
363 | |||
364 | source = link->source->entity; | ||
365 | sink = link->sink->entity; | ||
366 | |||
367 | mdev = source->parent; | ||
368 | |||
369 | if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) { | ||
370 | ret = mdev->link_notify(link->source, link->sink, | ||
371 | MEDIA_LNK_FL_ENABLED); | ||
372 | if (ret < 0) | ||
373 | return ret; | ||
374 | } | ||
375 | |||
376 | ret = __media_entity_setup_link_notify(link, flags); | ||
377 | if (ret < 0) | ||
378 | goto err; | ||
379 | |||
380 | if (!(flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) | ||
381 | mdev->link_notify(link->source, link->sink, 0); | ||
382 | |||
383 | return 0; | ||
384 | |||
385 | err: | ||
386 | if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) | ||
387 | mdev->link_notify(link->source, link->sink, 0); | ||
388 | |||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | int media_entity_setup_link(struct media_link *link, u32 flags) | ||
393 | { | ||
394 | int ret; | ||
395 | |||
396 | mutex_lock(&link->source->entity->parent->graph_mutex); | ||
397 | ret = __media_entity_setup_link(link, flags); | ||
398 | mutex_unlock(&link->source->entity->parent->graph_mutex); | ||
399 | |||
400 | return ret; | ||
401 | } | ||
402 | EXPORT_SYMBOL_GPL(media_entity_setup_link); | ||
403 | |||
404 | /** | ||
405 | * media_entity_find_link - Find a link between two pads | ||
406 | * @source: Source pad | ||
407 | * @sink: Sink pad | ||
408 | * | ||
409 | * Return a pointer to the link between the two entities. If no such link | ||
410 | * exists, return NULL. | ||
411 | */ | ||
412 | struct media_link * | ||
413 | media_entity_find_link(struct media_pad *source, struct media_pad *sink) | ||
414 | { | ||
415 | struct media_link *link; | ||
416 | unsigned int i; | ||
417 | |||
418 | for (i = 0; i < source->entity->num_links; ++i) { | ||
419 | link = &source->entity->links[i]; | ||
420 | |||
421 | if (link->source->entity == source->entity && | ||
422 | link->source->index == source->index && | ||
423 | link->sink->entity == sink->entity && | ||
424 | link->sink->index == sink->index) | ||
425 | return link; | ||
426 | } | ||
427 | |||
428 | return NULL; | ||
429 | } | ||
430 | EXPORT_SYMBOL_GPL(media_entity_find_link); | ||
431 | |||
432 | /** | ||
433 | * media_entity_remote_source - Find the source pad at the remote end of a link | ||
434 | * @pad: Sink pad at the local end of the link | ||
435 | * | ||
436 | * Search for a remote source pad connected to the given sink pad by iterating | ||
437 | * over all links originating or terminating at that pad until an enabled link | ||
438 | * is found. | ||
439 | * | ||
440 | * Return a pointer to the pad at the remote end of the first found enabled | ||
441 | * link, or NULL if no enabled link has been found. | ||
442 | */ | ||
443 | struct media_pad *media_entity_remote_source(struct media_pad *pad) | ||
444 | { | ||
445 | unsigned int i; | ||
446 | |||
447 | for (i = 0; i < pad->entity->num_links; i++) { | ||
448 | struct media_link *link = &pad->entity->links[i]; | ||
449 | |||
450 | if (!(link->flags & MEDIA_LNK_FL_ENABLED)) | ||
451 | continue; | ||
452 | |||
453 | if (link->source == pad) | ||
454 | return link->sink; | ||
455 | |||
456 | if (link->sink == pad) | ||
457 | return link->source; | ||
458 | } | ||
459 | |||
460 | return NULL; | ||
461 | |||
462 | } | ||
463 | EXPORT_SYMBOL_GPL(media_entity_remote_source); | ||
diff --git a/include/linux/media.h b/include/linux/media.h index 17c93a413677..7c69913c0ad2 100644 --- a/include/linux/media.h +++ b/include/linux/media.h | |||
@@ -126,5 +126,6 @@ struct media_links_enum { | |||
126 | #define MEDIA_IOC_DEVICE_INFO _IOWR('M', 1, struct media_device_info) | 126 | #define MEDIA_IOC_DEVICE_INFO _IOWR('M', 1, struct media_device_info) |
127 | #define MEDIA_IOC_ENUM_ENTITIES _IOWR('M', 2, struct media_entity_desc) | 127 | #define MEDIA_IOC_ENUM_ENTITIES _IOWR('M', 2, struct media_entity_desc) |
128 | #define MEDIA_IOC_ENUM_LINKS _IOWR('M', 3, struct media_links_enum) | 128 | #define MEDIA_IOC_ENUM_LINKS _IOWR('M', 3, struct media_links_enum) |
129 | #define MEDIA_IOC_SETUP_LINK _IOWR('M', 4, struct media_link_desc) | ||
129 | 130 | ||
130 | #endif /* __LINUX_MEDIA_H */ | 131 | #endif /* __LINUX_MEDIA_H */ |
diff --git a/include/media/media-device.h b/include/media/media-device.h index 5d2bff4fc9e0..6a27d916c250 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h | |||
@@ -73,6 +73,9 @@ struct media_device { | |||
73 | spinlock_t lock; | 73 | spinlock_t lock; |
74 | /* Serializes graph operations. */ | 74 | /* Serializes graph operations. */ |
75 | struct mutex graph_mutex; | 75 | struct mutex graph_mutex; |
76 | |||
77 | int (*link_notify)(struct media_pad *source, | ||
78 | struct media_pad *sink, u32 flags); | ||
76 | }; | 79 | }; |
77 | 80 | ||
78 | /* media_devnode to media_device */ | 81 | /* media_devnode to media_device */ |
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 51bdafce72c7..d889dcc67d0d 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h | |||
@@ -39,6 +39,12 @@ struct media_pad { | |||
39 | unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ | 39 | unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct media_entity_operations { | ||
43 | int (*link_setup)(struct media_entity *entity, | ||
44 | const struct media_pad *local, | ||
45 | const struct media_pad *remote, u32 flags); | ||
46 | }; | ||
47 | |||
42 | struct media_entity { | 48 | struct media_entity { |
43 | struct list_head list; | 49 | struct list_head list; |
44 | struct media_device *parent; /* Media device this entity belongs to*/ | 50 | struct media_device *parent; /* Media device this entity belongs to*/ |
@@ -59,6 +65,8 @@ struct media_entity { | |||
59 | struct media_pad *pads; /* Pads array (num_pads elements) */ | 65 | struct media_pad *pads; /* Pads array (num_pads elements) */ |
60 | struct media_link *links; /* Links array (max_links elements)*/ | 66 | struct media_link *links; /* Links array (max_links elements)*/ |
61 | 67 | ||
68 | const struct media_entity_operations *ops; /* Entity operations */ | ||
69 | |||
62 | /* Reference counts must never be negative, but are signed integers on | 70 | /* Reference counts must never be negative, but are signed integers on |
63 | * purpose: a simple WARN_ON(<0) check can be used to detect reference | 71 | * purpose: a simple WARN_ON(<0) check can be used to detect reference |
64 | * count bugs that would make them negative. | 72 | * count bugs that would make them negative. |
@@ -112,6 +120,11 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, | |||
112 | void media_entity_cleanup(struct media_entity *entity); | 120 | void media_entity_cleanup(struct media_entity *entity); |
113 | int media_entity_create_link(struct media_entity *source, u16 source_pad, | 121 | int media_entity_create_link(struct media_entity *source, u16 source_pad, |
114 | struct media_entity *sink, u16 sink_pad, u32 flags); | 122 | struct media_entity *sink, u16 sink_pad, u32 flags); |
123 | int __media_entity_setup_link(struct media_link *link, u32 flags); | ||
124 | int media_entity_setup_link(struct media_link *link, u32 flags); | ||
125 | struct media_link *media_entity_find_link(struct media_pad *source, | ||
126 | struct media_pad *sink); | ||
127 | struct media_pad *media_entity_remote_source(struct media_pad *pad); | ||
115 | 128 | ||
116 | struct media_entity *media_entity_get(struct media_entity *entity); | 129 | struct media_entity *media_entity_get(struct media_entity *entity); |
117 | void media_entity_put(struct media_entity *entity); | 130 | void media_entity_put(struct media_entity *entity); |
@@ -121,4 +134,8 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, | |||
121 | struct media_entity * | 134 | struct media_entity * |
122 | media_entity_graph_walk_next(struct media_entity_graph *graph); | 135 | media_entity_graph_walk_next(struct media_entity_graph *graph); |
123 | 136 | ||
137 | #define media_entity_call(entity, operation, args...) \ | ||
138 | (((entity)->ops && (entity)->ops->operation) ? \ | ||
139 | (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) | ||
140 | |||
124 | #endif | 141 | #endif |