Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b01cc9ce authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

[media] media-entitiy: add a function to create multiple links



Sometimes, it is desired to create 1:n and n:1 or even
n:n links between different entities with the same
function.

This is actually needed to support DVB devices that
have multiple frontends. While we could do a function
like that internally at the DVB core, such function is
generic enough to be at media-entity, and it could be
useful on some other places.

So, add such function.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 33c68533
Loading
Loading
Loading
Loading
+65 −0
Original line number Diff line number Diff line
@@ -625,6 +625,71 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
}
EXPORT_SYMBOL_GPL(media_create_pad_link);

int media_create_pad_links(const struct media_device *mdev,
			   const u32 source_function,
			   struct media_entity *source,
			   const u16 source_pad,
			   const u32 sink_function,
			   struct media_entity *sink,
			   const u16 sink_pad,
			   u32 flags,
			   const bool allow_both_undefined)
{
	struct media_entity *entity;
	unsigned function;
	int ret;

	/* Trivial case: 1:1 relation */
	if (source && sink)
		return media_create_pad_link(source, source_pad,
					     sink, sink_pad, flags);

	/* Worse case scenario: n:n relation */
	if (!source && !sink) {
		if (!allow_both_undefined)
			return 0;
		media_device_for_each_entity(source, mdev) {
			if (source->function != source_function)
				continue;
			media_device_for_each_entity(sink, mdev) {
				if (sink->function != sink_function)
					continue;
				ret = media_create_pad_link(source, source_pad,
							    sink, sink_pad,
							    flags);
				if (ret)
					return ret;
				flags &= ~(MEDIA_LNK_FL_ENABLED |
					   MEDIA_LNK_FL_IMMUTABLE);
			}
		}
		return 0;
	}

	/* Handle 1:n and n:1 cases */
	if (source)
		function = sink_function;
	else
		function = source_function;

	media_device_for_each_entity(entity, mdev) {
		if (entity->function != function)
			continue;

		if (source)
			ret = media_create_pad_link(source, source_pad,
						    entity, sink_pad, flags);
		else
			ret = media_create_pad_link(entity, source_pad,
						    sink, sink_pad, flags);
		if (ret)
			return ret;
		flags &= ~(MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
	}
	return 0;
}
EXPORT_SYMBOL_GPL(media_create_pad_links);

void __media_entity_remove_links(struct media_entity *entity)
{
	struct media_link *link, *tmp;
+51 −0
Original line number Diff line number Diff line
@@ -613,6 +613,57 @@ static inline void media_entity_cleanup(struct media_entity *entity) {};
__must_check int media_create_pad_link(struct media_entity *source,
			u16 source_pad, struct media_entity *sink,
			u16 sink_pad, u32 flags);

/**
 * media_create_pad_links() - creates a link between two entities.
 *
 * @mdev: Pointer to the media_device that contains the object
 * @source_function: Function of the source entities. Used only if @source is
 *	NULL.
 * @source: pointer to &media_entity of the source pad. If NULL, it will use
 * 	all entities that matches the @sink_function.
 * @source_pad: number of the source pad in the pads array
 * @sink_function: Function of the sink entities. Used only if @sink is NULL.
 * @sink: pointer to &media_entity of the sink pad. If NULL, it will use
 * 	all entities that matches the @sink_function.
 * @sink_pad: number of the sink pad in the pads array.
 * @flags: Link flags, as defined in include/uapi/linux/media.h.
 * @allow_both_undefined: if true, then both @source and @sink can be NULL.
 *	In such case, it will create a crossbar between all entities that
 *	matches @source_function to all entities that matches @sink_function.
 *	If false, it will return 0 and won't create any link if both @source
 *	and @sink are NULL.
 *
 * Valid values for flags:
 * A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can be
 *	used to transfer media data. If multiple links are created and this
 *	flag is passed as an argument, only the first created link will have
 *	this flag.
 *
 * A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't
 *	be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then
 *	%MEDIA_LNK_FL_ENABLED must also be set since an immutable link is
 *	always enabled.
 *
 * It is common for some devices to have multiple source and/or sink entities
 * of the same type that should be linked. While media_create_pad_link()
 * creates link by link, this function is meant to allow 1:n, n:1 and even
 * cross-bar (n:n) links.
 *
 * NOTE: Before calling this function, media_entity_pads_init() and
 * media_device_register_entity() should be called previously for the entities
 * to be linked.
 */
int media_create_pad_links(const struct media_device *mdev,
			   const u32 source_function,
			   struct media_entity *source,
			   const u16 source_pad,
			   const u32 sink_function,
			   struct media_entity *sink,
			   const u16 sink_pad,
			   u32 flags,
			   const bool allow_both_undefined);

void __media_entity_remove_links(struct media_entity *entity);

/**