Commit eac564de authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

media: mc: entity: Add entity iterator for media_pipeline



Add a media_pipeline_for_each_entity() macro to iterate over entities in
a pipeline. This should be used by driver as a replacement of the
media_graph_walk API, as iterating over the media_pipeline uses the
cached list of pads and is thus more efficient.

Deprecate the media_graph_walk API to indicate it shouldn't be used in
new drivers.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent d10ac51e
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -963,6 +963,43 @@ __media_pipeline_pad_iter_next(struct media_pipeline *pipe,
}
EXPORT_SYMBOL_GPL(__media_pipeline_pad_iter_next);

int media_pipeline_entity_iter_init(struct media_pipeline *pipe,
				    struct media_pipeline_entity_iter *iter)
{
	return media_entity_enum_init(&iter->ent_enum, pipe->mdev);
}
EXPORT_SYMBOL_GPL(media_pipeline_entity_iter_init);

void media_pipeline_entity_iter_cleanup(struct media_pipeline_entity_iter *iter)
{
	media_entity_enum_cleanup(&iter->ent_enum);
}
EXPORT_SYMBOL_GPL(media_pipeline_entity_iter_cleanup);

struct media_entity *
__media_pipeline_entity_iter_next(struct media_pipeline *pipe,
				  struct media_pipeline_entity_iter *iter,
				  struct media_entity *entity)
{
	if (!entity)
		iter->cursor = pipe->pads.next;

	while (iter->cursor != &pipe->pads) {
		struct media_pipeline_pad *ppad;
		struct media_entity *entity;

		ppad = list_entry(iter->cursor, struct media_pipeline_pad, list);
		entity = ppad->pad->entity;
		iter->cursor = iter->cursor->next;

		if (!media_entity_enum_test_and_set(&iter->ent_enum, entity))
			return entity;
	}

	return NULL;
}
EXPORT_SYMBOL_GPL(__media_pipeline_entity_iter_next);

/* -----------------------------------------------------------------------------
 * Links management
 */
+69 −0
Original line number Diff line number Diff line
@@ -139,6 +139,17 @@ struct media_pipeline_pad_iter {
	struct list_head *cursor;
};

/**
 * struct media_pipeline_entity_iter - Iterator for media_pipeline_for_each_entity
 *
 * @ent_enum: The entity enumeration tracker
 * @cursor: The current element
 */
struct media_pipeline_entity_iter {
	struct media_entity_enum ent_enum;
	struct list_head *cursor;
};

/**
 * struct media_link - A link object part of a media graph.
 *
@@ -1077,6 +1088,8 @@ int media_entity_get_fwnode_pad(struct media_entity *entity,
 * @graph: Media graph structure that will be used to walk the graph
 * @mdev: Pointer to the &media_device that contains the object
 *
 * This function is deprecated, use media_pipeline_for_each_pad() instead.
 *
 * The caller is required to hold the media_device graph_mutex during the graph
 * walk until the graph state is released.
 *
@@ -1089,6 +1102,8 @@ __must_check int media_graph_walk_init(
 * media_graph_walk_cleanup - Release resources used by graph walk.
 *
 * @graph: Media graph structure that will be used to walk the graph
 *
 * This function is deprecated, use media_pipeline_for_each_pad() instead.
 */
void media_graph_walk_cleanup(struct media_graph *graph);

@@ -1099,6 +1114,8 @@ void media_graph_walk_cleanup(struct media_graph *graph);
 * @graph: Media graph structure that will be used to walk the graph
 * @entity: Starting entity
 *
 * This function is deprecated, use media_pipeline_for_each_pad() instead.
 *
 * Before using this function, media_graph_walk_init() must be
 * used to allocate resources used for walking the graph. This
 * function initializes the graph traversal structure to walk the
@@ -1114,6 +1131,8 @@ void media_graph_walk_start(struct media_graph *graph,
 * media_graph_walk_next - Get the next entity in the graph
 * @graph: Media graph structure
 *
 * This function is deprecated, use media_pipeline_for_each_pad() instead.
 *
 * Perform a depth-first traversal of the given media entities graph.
 *
 * The graph structure must have been previously initialized with a call to
@@ -1194,6 +1213,56 @@ __media_pipeline_pad_iter_next(struct media_pipeline *pipe,
	     pad != NULL;						\
	     pad = __media_pipeline_pad_iter_next((pipe), iter, pad))

/**
 * media_pipeline_entity_iter_init - Initialize a pipeline entity iterator
 * @pipe: The pipeline
 * @iter: The iterator
 *
 * This function must be called to initialize the iterator before using it in a
 * media_pipeline_for_each_entity() loop. The iterator must be destroyed by a
 * call to media_pipeline_entity_iter_cleanup after the loop (including in code
 * paths that break from the loop).
 *
 * The same iterator can be used in multiple consecutive loops without being
 * destroyed and reinitialized.
 *
 * Return: 0 on success or a negative error code otherwise.
 */
int media_pipeline_entity_iter_init(struct media_pipeline *pipe,
				    struct media_pipeline_entity_iter *iter);

/**
 * media_pipeline_entity_iter_cleanup - Destroy a pipeline entity iterator
 * @iter: The iterator
 *
 * This function must be called to destroy iterators initialized with
 * media_pipeline_entity_iter_init().
 */
void media_pipeline_entity_iter_cleanup(struct media_pipeline_entity_iter *iter);

struct media_entity *
__media_pipeline_entity_iter_next(struct media_pipeline *pipe,
				  struct media_pipeline_entity_iter *iter,
				  struct media_entity *entity);

/**
 * media_pipeline_for_each_entity - Iterate on all entities in a media pipeline
 * @pipe: The pipeline
 * @iter: The iterator (struct media_pipeline_entity_iter)
 * @entity: The iterator entity
 *
 * Iterate on all entities in a media pipeline. This is only valid after the
 * pipeline has been built with media_pipeline_start() and before it gets
 * destroyed with media_pipeline_stop(). The iterator must be initialized with
 * media_pipeline_entity_iter_init() before iteration, and destroyed with
 * media_pipeline_entity_iter_cleanup() after (including in code paths that
 * break from the loop).
 */
#define media_pipeline_for_each_entity(pipe, iter, entity)			\
	for (entity = __media_pipeline_entity_iter_next((pipe), iter, NULL);	\
	     entity != NULL;							\
	     entity = __media_pipeline_entity_iter_next((pipe), iter, entity))

/**
 * media_pipeline_alloc_start - Mark a pipeline as streaming
 * @pad: Starting pad