aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/media-entity.c
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@iki.fi>2012-01-11 04:25:15 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 07:44:11 -0400
commitaf88be3887c1a0b20d0792c3c237a67c73ef3286 (patch)
tree79047160436c63bab20241807a61d8030b6a0527 /drivers/media/media-entity.c
parent440f0fadd407c66abe285ce26ed8c31fb2403f0d (diff)
[media] media: Add link_validate() op to check links to the sink pad
The purpose of the link_validate() op is to allow an entity driver to ensure that the properties of the pads at the both ends of the link are suitable for starting the pipeline. link_validate is called on sink pads on active links which belong to the active part of the graph. Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/media-entity.c')
-rw-r--r--drivers/media/media-entity.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 056138f63c7d..e1cd13283407 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -214,23 +214,76 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
214 * pipeline pointer must be identical for all nested calls to 214 * pipeline pointer must be identical for all nested calls to
215 * media_entity_pipeline_start(). 215 * media_entity_pipeline_start().
216 */ 216 */
217void media_entity_pipeline_start(struct media_entity *entity, 217__must_check int media_entity_pipeline_start(struct media_entity *entity,
218 struct media_pipeline *pipe) 218 struct media_pipeline *pipe)
219{ 219{
220 struct media_device *mdev = entity->parent; 220 struct media_device *mdev = entity->parent;
221 struct media_entity_graph graph; 221 struct media_entity_graph graph;
222 struct media_entity *entity_err = entity;
223 int ret;
222 224
223 mutex_lock(&mdev->graph_mutex); 225 mutex_lock(&mdev->graph_mutex);
224 226
225 media_entity_graph_walk_start(&graph, entity); 227 media_entity_graph_walk_start(&graph, entity);
226 228
227 while ((entity = media_entity_graph_walk_next(&graph))) { 229 while ((entity = media_entity_graph_walk_next(&graph))) {
230 unsigned int i;
231
228 entity->stream_count++; 232 entity->stream_count++;
229 WARN_ON(entity->pipe && entity->pipe != pipe); 233 WARN_ON(entity->pipe && entity->pipe != pipe);
230 entity->pipe = pipe; 234 entity->pipe = pipe;
235
236 /* Already streaming --- no need to check. */
237 if (entity->stream_count > 1)
238 continue;
239
240 if (!entity->ops || !entity->ops->link_validate)
241 continue;
242
243 for (i = 0; i < entity->num_links; i++) {
244 struct media_link *link = &entity->links[i];
245
246 /* Is this pad part of an enabled link? */
247 if (!(link->flags & MEDIA_LNK_FL_ENABLED))
248 continue;
249
250 /* Are we the sink or not? */
251 if (link->sink->entity != entity)
252 continue;
253
254 ret = entity->ops->link_validate(link);
255 if (ret < 0 && ret != -ENOIOCTLCMD)
256 goto error;
257 }
231 } 258 }
232 259
233 mutex_unlock(&mdev->graph_mutex); 260 mutex_unlock(&mdev->graph_mutex);
261
262 return 0;
263
264error:
265 /*
266 * Link validation on graph failed. We revert what we did and
267 * return the error.
268 */
269 media_entity_graph_walk_start(&graph, entity_err);
270
271 while ((entity_err = media_entity_graph_walk_next(&graph))) {
272 entity_err->stream_count--;
273 if (entity_err->stream_count == 0)
274 entity_err->pipe = NULL;
275
276 /*
277 * We haven't increased stream_count further than this
278 * so we quit here.
279 */
280 if (entity_err == entity)
281 break;
282 }
283
284 mutex_unlock(&mdev->graph_mutex);
285
286 return ret;
234} 287}
235EXPORT_SYMBOL_GPL(media_entity_pipeline_start); 288EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
236 289