summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap/media/0011-media-Entity-graph-traversal.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/media/0011-media-Entity-graph-traversal.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap/media/0011-media-Entity-graph-traversal.patch228
1 files changed, 228 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/media/0011-media-Entity-graph-traversal.patch b/extras/recipes-kernel/linux/linux-omap/media/0011-media-Entity-graph-traversal.patch
new file mode 100644
index 00000000..15fc6123
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap/media/0011-media-Entity-graph-traversal.patch
@@ -0,0 +1,228 @@
1From 5b45472e8a692e6acea3cb6d601b44c17ea8d59e Mon Sep 17 00:00:00 2001
2From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
3Date: Sun, 7 Mar 2010 21:14:14 +0200
4Subject: [PATCH 11/43] media: Entity graph traversal
5
6Add media entity graph traversal. The traversal follows enabled links by
7depth first. Traversing graph backwards is prevented by comparing the next
8possible entity in the graph with the previous one. Multiply connected
9graphs are thus not supported.
10
11Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
12Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
13Signed-off-by: Vimarsh Zutshi <vimarsh.zutshi@nokia.com>
14---
15 Documentation/media-framework.txt | 42 +++++++++++++
16 drivers/media/media-entity.c | 115 +++++++++++++++++++++++++++++++++++++
17 include/media/media-entity.h | 15 +++++
18 3 files changed, 172 insertions(+), 0 deletions(-)
19
20diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
21index b252cf9..88fe379 100644
22--- a/Documentation/media-framework.txt
23+++ b/Documentation/media-framework.txt
24@@ -216,3 +216,45 @@ Links have flags that describe the link capabilities and state.
25 modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then
26 MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always
27 enabled.
28+
29+
30+Graph traversal
31+---------------
32+
33+The media framework provides APIs to iterate over entities in a graph.
34+
35+To iterate over all entities belonging to a media device, drivers can use the
36+media_device_for_each_entity macro, defined in include/media/media-device.h.
37+
38+ struct media_entity *entity;
39+
40+ media_device_for_each_entity(entity, mdev) {
41+ /* entity will point to each entity in turn */
42+ ...
43+ }
44+
45+Drivers might also need to iterate over all entities in a graph that can be
46+reached only through enabled links starting at a given entity. The media
47+framework provides a depth-first graph traversal API for that purpose.
48+
49+Note that graphs with cycles (whether directed or undirected) are *NOT*
50+supported by the graph traversal API. To prevent infinite loops, the graph
51+traversal code limits the maximum depth to MEDIA_ENTITY_ENUM_MAX_DEPTH,
52+currently defined as 16.
53+
54+Drivers initiate a graph traversal by calling
55+
56+ media_entity_graph_walk_start(struct media_entity_graph *graph,
57+ struct media_entity *entity);
58+
59+The graph structure, provided by the caller, is initialized to start graph
60+traversal at the given entity.
61+
62+Drivers can then retrieve the next entity by calling
63+
64+ media_entity_graph_walk_next(struct media_entity_graph *graph);
65+
66+When the graph traversal is complete the function will return NULL.
67+
68+Graph traversal can be interrupted at any moment. No cleanup function call is
69+required and the graph structure can be freed normally.
70diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
71index e4ba2bc..a805f20 100644
72--- a/drivers/media/media-entity.c
73+++ b/drivers/media/media-entity.c
74@@ -84,6 +84,121 @@ media_entity_cleanup(struct media_entity *entity)
75 }
76 EXPORT_SYMBOL_GPL(media_entity_cleanup);
77
78+/* -----------------------------------------------------------------------------
79+ * Graph traversal
80+ */
81+
82+static struct media_entity *
83+media_entity_other(struct media_entity *entity, struct media_link *link)
84+{
85+ if (link->source->entity == entity)
86+ return link->sink->entity;
87+ else
88+ return link->source->entity;
89+}
90+
91+/* push an entity to traversal stack */
92+static void stack_push(struct media_entity_graph *graph,
93+ struct media_entity *entity)
94+{
95+ if (graph->top == MEDIA_ENTITY_ENUM_MAX_DEPTH - 1) {
96+ WARN_ON(1);
97+ return;
98+ }
99+ graph->top++;
100+ graph->stack[graph->top].link = 0;
101+ graph->stack[graph->top].entity = entity;
102+}
103+
104+static struct media_entity *stack_pop(struct media_entity_graph *graph)
105+{
106+ struct media_entity *entity;
107+
108+ entity = graph->stack[graph->top].entity;
109+ graph->top--;
110+
111+ return entity;
112+}
113+
114+#define stack_peek(en) ((en)->stack[(en)->top - 1].entity)
115+#define link_top(en) ((en)->stack[(en)->top].link)
116+#define stack_top(en) ((en)->stack[(en)->top].entity)
117+
118+/**
119+ * media_entity_graph_walk_start - Start walking the media graph at a given entity
120+ * @graph: Media graph structure that will be used to walk the graph
121+ * @entity: Starting entity
122+ *
123+ * This function initializes the graph traversal structure to walk the entities
124+ * graph starting at the given entity. The traversal structure must not be
125+ * modified by the caller during graph traversal. When done the structure can
126+ * safely be freed.
127+ */
128+void media_entity_graph_walk_start(struct media_entity_graph *graph,
129+ struct media_entity *entity)
130+{
131+ graph->top = 0;
132+ graph->stack[graph->top].entity = NULL;
133+ stack_push(graph, entity);
134+}
135+EXPORT_SYMBOL_GPL(media_entity_graph_walk_start);
136+
137+/**
138+ * media_entity_graph_walk_next - Get the next entity in the graph
139+ * @graph: Media graph structure
140+ *
141+ * Perform a depth-first traversal of the given media entities graph.
142+ *
143+ * The graph structure must have been previously initialized with a call to
144+ * media_entity_graph_walk_start().
145+ *
146+ * Return the next entity in the graph or NULL if the whole graph have been
147+ * traversed.
148+ */
149+struct media_entity *
150+media_entity_graph_walk_next(struct media_entity_graph *graph)
151+{
152+ if (stack_top(graph) == NULL)
153+ return NULL;
154+
155+ /*
156+ * Depth first search. Push entity to stack and continue from
157+ * top of the stack until no more entities on the level can be
158+ * found.
159+ */
160+ while (link_top(graph) < stack_top(graph)->num_links) {
161+ struct media_entity *entity = stack_top(graph);
162+ struct media_link *link = &entity->links[link_top(graph)];
163+ struct media_entity *next;
164+
165+ /* The link is not enabled so we do not follow. */
166+ if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
167+ link_top(graph)++;
168+ continue;
169+ }
170+
171+ /* Get the entity in the other end of the link . */
172+ next = media_entity_other(entity, link);
173+
174+ /* Was it the entity we came here from? */
175+ if (next == stack_peek(graph)) {
176+ link_top(graph)++;
177+ continue;
178+ }
179+
180+ /* Push the new entity to stack and start over. */
181+ link_top(graph)++;
182+ stack_push(graph, next);
183+ }
184+
185+ return stack_pop(graph);
186+}
187+EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
188+
189+/* -----------------------------------------------------------------------------
190+ * Links management
191+ */
192+
193 static struct media_link *media_entity_add_link(struct media_entity *entity)
194 {
195 if (entity->num_links >= entity->max_links) {
196diff --git a/include/media/media-entity.h b/include/media/media-entity.h
197index 7cf9135..b82f824 100644
198--- a/include/media/media-entity.h
199+++ b/include/media/media-entity.h
200@@ -113,10 +113,25 @@ static inline u32 media_entity_subtype(struct media_entity *entity)
201 return entity->type & MEDIA_ENT_SUBTYPE_MASK;
202 }
203
204+#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16
205+
206+struct media_entity_graph {
207+ struct {
208+ struct media_entity *entity;
209+ int link;
210+ } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH];
211+ int top;
212+};
213+
214 int media_entity_init(struct media_entity *entity, u16 num_pads,
215 struct media_pad *pads, u16 extra_links);
216 void media_entity_cleanup(struct media_entity *entity);
217 int media_entity_create_link(struct media_entity *source, u16 source_pad,
218 struct media_entity *sink, u16 sink_pad, u32 flags);
219
220+void media_entity_graph_walk_start(struct media_entity_graph *graph,
221+ struct media_entity *entity);
222+struct media_entity *
223+media_entity_graph_walk_next(struct media_entity_graph *graph);
224+
225 #endif
226--
2271.6.6.1
228