xref: /linux/drivers/media/mc/mc-entity.c (revision 72b603357ae461c0f19ca05d6624b4afd5c74b47)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Media entity
4  *
5  * Copyright (C) 2010 Nokia Corporation
6  *
7  * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
8  *	     Sakari Ailus <sakari.ailus@iki.fi>
9  */
10 
11 #include <linux/bitmap.h>
12 #include <linux/list.h>
13 #include <linux/property.h>
14 #include <linux/slab.h>
15 #include <media/media-entity.h>
16 #include <media/media-device.h>
17 
18 static inline const char *intf_type(struct media_interface *intf)
19 {
20 	switch (intf->type) {
21 	case MEDIA_INTF_T_DVB_FE:
22 		return "dvb-frontend";
23 	case MEDIA_INTF_T_DVB_DEMUX:
24 		return "dvb-demux";
25 	case MEDIA_INTF_T_DVB_DVR:
26 		return "dvb-dvr";
27 	case MEDIA_INTF_T_DVB_CA:
28 		return  "dvb-ca";
29 	case MEDIA_INTF_T_DVB_NET:
30 		return "dvb-net";
31 	case MEDIA_INTF_T_V4L_VIDEO:
32 		return "v4l-video";
33 	case MEDIA_INTF_T_V4L_VBI:
34 		return "v4l-vbi";
35 	case MEDIA_INTF_T_V4L_RADIO:
36 		return "v4l-radio";
37 	case MEDIA_INTF_T_V4L_SUBDEV:
38 		return "v4l-subdev";
39 	case MEDIA_INTF_T_V4L_SWRADIO:
40 		return "v4l-swradio";
41 	case MEDIA_INTF_T_V4L_TOUCH:
42 		return "v4l-touch";
43 	default:
44 		return "unknown-intf";
45 	}
46 };
47 
48 static inline const char *link_type_name(struct media_link *link)
49 {
50 	switch (link->flags & MEDIA_LNK_FL_LINK_TYPE) {
51 	case MEDIA_LNK_FL_DATA_LINK:
52 		return "data";
53 	case MEDIA_LNK_FL_INTERFACE_LINK:
54 		return "interface";
55 	case MEDIA_LNK_FL_ANCILLARY_LINK:
56 		return "ancillary";
57 	default:
58 		return "unknown";
59 	}
60 }
61 
62 __must_check int media_entity_enum_init(struct media_entity_enum *ent_enum,
63 					struct media_device *mdev)
64 {
65 	int idx_max;
66 
67 	idx_max = ALIGN(mdev->entity_internal_idx_max + 1, BITS_PER_LONG);
68 	ent_enum->bmap = bitmap_zalloc(idx_max, GFP_KERNEL);
69 	if (!ent_enum->bmap)
70 		return -ENOMEM;
71 
72 	ent_enum->idx_max = idx_max;
73 
74 	return 0;
75 }
76 EXPORT_SYMBOL_GPL(media_entity_enum_init);
77 
78 void media_entity_enum_cleanup(struct media_entity_enum *ent_enum)
79 {
80 	bitmap_free(ent_enum->bmap);
81 }
82 EXPORT_SYMBOL_GPL(media_entity_enum_cleanup);
83 
84 /**
85  *  dev_dbg_obj - Prints in debug mode a change on some object
86  *
87  * @event_name:	Name of the event to report. Could be __func__
88  * @gobj:	Pointer to the object
89  *
90  * Enabled only if DEBUG or CONFIG_DYNAMIC_DEBUG. Otherwise, it
91  * won't produce any code.
92  */
93 static void dev_dbg_obj(const char *event_name,  struct media_gobj *gobj)
94 {
95 #if defined(DEBUG) || defined (CONFIG_DYNAMIC_DEBUG)
96 	switch (media_type(gobj)) {
97 	case MEDIA_GRAPH_ENTITY:
98 		dev_dbg(gobj->mdev->dev,
99 			"%s id %u: entity '%s'\n",
100 			event_name, media_id(gobj),
101 			gobj_to_entity(gobj)->name);
102 		break;
103 	case MEDIA_GRAPH_LINK:
104 	{
105 		struct media_link *link = gobj_to_link(gobj);
106 
107 		dev_dbg(gobj->mdev->dev,
108 			"%s id %u: %s link id %u ==> id %u\n",
109 			event_name, media_id(gobj), link_type_name(link),
110 			media_id(link->gobj0),
111 			media_id(link->gobj1));
112 		break;
113 	}
114 	case MEDIA_GRAPH_PAD:
115 	{
116 		struct media_pad *pad = gobj_to_pad(gobj);
117 
118 		dev_dbg(gobj->mdev->dev,
119 			"%s id %u: %s%spad '%s':%d\n",
120 			event_name, media_id(gobj),
121 			pad->flags & MEDIA_PAD_FL_SINK   ? "sink " : "",
122 			pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "",
123 			pad->entity->name, pad->index);
124 		break;
125 	}
126 	case MEDIA_GRAPH_INTF_DEVNODE:
127 	{
128 		struct media_interface *intf = gobj_to_intf(gobj);
129 		struct media_intf_devnode *devnode = intf_to_devnode(intf);
130 
131 		dev_dbg(gobj->mdev->dev,
132 			"%s id %u: intf_devnode %s - major: %d, minor: %d\n",
133 			event_name, media_id(gobj),
134 			intf_type(intf),
135 			devnode->major, devnode->minor);
136 		break;
137 	}
138 	}
139 #endif
140 }
141 
142 void media_gobj_create(struct media_device *mdev,
143 			   enum media_gobj_type type,
144 			   struct media_gobj *gobj)
145 {
146 	BUG_ON(!mdev);
147 
148 	gobj->mdev = mdev;
149 
150 	/* Create a per-type unique object ID */
151 	gobj->id = media_gobj_gen_id(type, ++mdev->id);
152 
153 	switch (type) {
154 	case MEDIA_GRAPH_ENTITY:
155 		list_add_tail(&gobj->list, &mdev->entities);
156 		break;
157 	case MEDIA_GRAPH_PAD:
158 		list_add_tail(&gobj->list, &mdev->pads);
159 		break;
160 	case MEDIA_GRAPH_LINK:
161 		list_add_tail(&gobj->list, &mdev->links);
162 		break;
163 	case MEDIA_GRAPH_INTF_DEVNODE:
164 		list_add_tail(&gobj->list, &mdev->interfaces);
165 		break;
166 	}
167 
168 	mdev->topology_version++;
169 
170 	dev_dbg_obj(__func__, gobj);
171 }
172 
173 void media_gobj_destroy(struct media_gobj *gobj)
174 {
175 	/* Do nothing if the object is not linked. */
176 	if (gobj->mdev == NULL)
177 		return;
178 
179 	dev_dbg_obj(__func__, gobj);
180 
181 	gobj->mdev->topology_version++;
182 
183 	/* Remove the object from mdev list */
184 	list_del(&gobj->list);
185 
186 	gobj->mdev = NULL;
187 }
188 
189 /*
190  * TODO: Get rid of this.
191  */
192 #define MEDIA_ENTITY_MAX_PADS		512
193 
194 int media_entity_pads_init(struct media_entity *entity, u16 num_pads,
195 			   struct media_pad *pads)
196 {
197 	struct media_device *mdev = entity->graph_obj.mdev;
198 	struct media_pad *iter;
199 	unsigned int i = 0;
200 
201 	if (num_pads >= MEDIA_ENTITY_MAX_PADS)
202 		return -E2BIG;
203 
204 	entity->num_pads = num_pads;
205 	entity->pads = pads;
206 
207 	if (mdev)
208 		mutex_lock(&mdev->graph_mutex);
209 
210 	media_entity_for_each_pad(entity, iter) {
211 		iter->entity = entity;
212 		iter->index = i++;
213 		if (mdev)
214 			media_gobj_create(mdev, MEDIA_GRAPH_PAD,
215 					  &iter->graph_obj);
216 	}
217 
218 	if (mdev)
219 		mutex_unlock(&mdev->graph_mutex);
220 
221 	return 0;
222 }
223 EXPORT_SYMBOL_GPL(media_entity_pads_init);
224 
225 /* -----------------------------------------------------------------------------
226  * Graph traversal
227  */
228 
229 static struct media_entity *
230 media_entity_other(struct media_entity *entity, struct media_link *link)
231 {
232 	if (link->source->entity == entity)
233 		return link->sink->entity;
234 	else
235 		return link->source->entity;
236 }
237 
238 /* push an entity to traversal stack */
239 static void stack_push(struct media_graph *graph,
240 		       struct media_entity *entity)
241 {
242 	if (graph->top == MEDIA_ENTITY_ENUM_MAX_DEPTH - 1) {
243 		WARN_ON(1);
244 		return;
245 	}
246 	graph->top++;
247 	graph->stack[graph->top].link = entity->links.next;
248 	graph->stack[graph->top].entity = entity;
249 }
250 
251 static struct media_entity *stack_pop(struct media_graph *graph)
252 {
253 	struct media_entity *entity;
254 
255 	entity = graph->stack[graph->top].entity;
256 	graph->top--;
257 
258 	return entity;
259 }
260 
261 #define link_top(en)	((en)->stack[(en)->top].link)
262 #define stack_top(en)	((en)->stack[(en)->top].entity)
263 
264 /**
265  * media_graph_walk_init - Allocate resources for graph walk
266  * @graph: Media graph structure that will be used to walk the graph
267  * @mdev: Media device
268  *
269  * Reserve resources for graph walk in media device's current
270  * state. The memory must be released using
271  * media_graph_walk_free().
272  *
273  * Returns error on failure, zero on success.
274  */
275 __must_check int media_graph_walk_init(
276 	struct media_graph *graph, struct media_device *mdev)
277 {
278 	return media_entity_enum_init(&graph->ent_enum, mdev);
279 }
280 EXPORT_SYMBOL_GPL(media_graph_walk_init);
281 
282 /**
283  * media_graph_walk_cleanup - Release resources related to graph walking
284  * @graph: Media graph structure that was used to walk the graph
285  */
286 void media_graph_walk_cleanup(struct media_graph *graph)
287 {
288 	media_entity_enum_cleanup(&graph->ent_enum);
289 }
290 EXPORT_SYMBOL_GPL(media_graph_walk_cleanup);
291 
292 void media_graph_walk_start(struct media_graph *graph,
293 			    struct media_entity *entity)
294 {
295 	media_entity_enum_zero(&graph->ent_enum);
296 	media_entity_enum_set(&graph->ent_enum, entity);
297 
298 	graph->top = 0;
299 	graph->stack[graph->top].entity = NULL;
300 	stack_push(graph, entity);
301 	dev_dbg(entity->graph_obj.mdev->dev,
302 		"begin graph walk at '%s'\n", entity->name);
303 }
304 EXPORT_SYMBOL_GPL(media_graph_walk_start);
305 
306 static void media_graph_walk_iter(struct media_graph *graph)
307 {
308 	struct media_entity *entity = stack_top(graph);
309 	struct media_link *link;
310 	struct media_entity *next;
311 
312 	link = list_entry(link_top(graph), typeof(*link), list);
313 
314 	/* If the link is not a data link, don't follow it */
315 	if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) != MEDIA_LNK_FL_DATA_LINK) {
316 		link_top(graph) = link_top(graph)->next;
317 		return;
318 	}
319 
320 	/* The link is not enabled so we do not follow. */
321 	if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
322 		link_top(graph) = link_top(graph)->next;
323 		dev_dbg(entity->graph_obj.mdev->dev,
324 			"walk: skipping disabled link '%s':%u -> '%s':%u\n",
325 			link->source->entity->name, link->source->index,
326 			link->sink->entity->name, link->sink->index);
327 		return;
328 	}
329 
330 	/* Get the entity at the other end of the link. */
331 	next = media_entity_other(entity, link);
332 
333 	/* Has the entity already been visited? */
334 	if (media_entity_enum_test_and_set(&graph->ent_enum, next)) {
335 		link_top(graph) = link_top(graph)->next;
336 		dev_dbg(entity->graph_obj.mdev->dev,
337 			"walk: skipping entity '%s' (already seen)\n",
338 			next->name);
339 		return;
340 	}
341 
342 	/* Push the new entity to stack and start over. */
343 	link_top(graph) = link_top(graph)->next;
344 	stack_push(graph, next);
345 	dev_dbg(entity->graph_obj.mdev->dev, "walk: pushing '%s' on stack\n",
346 		next->name);
347 	lockdep_assert_held(&entity->graph_obj.mdev->graph_mutex);
348 }
349 
350 struct media_entity *media_graph_walk_next(struct media_graph *graph)
351 {
352 	struct media_entity *entity;
353 
354 	if (stack_top(graph) == NULL)
355 		return NULL;
356 
357 	/*
358 	 * Depth first search. Push entity to stack and continue from
359 	 * top of the stack until no more entities on the level can be
360 	 * found.
361 	 */
362 	while (link_top(graph) != &stack_top(graph)->links)
363 		media_graph_walk_iter(graph);
364 
365 	entity = stack_pop(graph);
366 	dev_dbg(entity->graph_obj.mdev->dev,
367 		"walk: returning entity '%s'\n", entity->name);
368 
369 	return entity;
370 }
371 EXPORT_SYMBOL_GPL(media_graph_walk_next);
372 
373 /* -----------------------------------------------------------------------------
374  * Pipeline management
375  */
376 
377 __must_check int __media_pipeline_start(struct media_entity *entity,
378 					struct media_pipeline *pipe)
379 {
380 	struct media_device *mdev = entity->graph_obj.mdev;
381 	struct media_graph *graph = &pipe->graph;
382 	struct media_entity *entity_err = entity;
383 	struct media_link *link;
384 	int ret;
385 
386 	if (pipe->start_count) {
387 		pipe->start_count++;
388 		return 0;
389 	}
390 
391 	ret = media_graph_walk_init(&pipe->graph, mdev);
392 	if (ret)
393 		return ret;
394 
395 	media_graph_walk_start(&pipe->graph, entity);
396 
397 	while ((entity = media_graph_walk_next(graph))) {
398 		DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS);
399 		DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS);
400 
401 		if (entity->pipe && entity->pipe != pipe) {
402 			pr_err("Pipe active for %s. Can't start for %s\n",
403 				entity->name,
404 				entity_err->name);
405 			ret = -EBUSY;
406 			goto error;
407 		}
408 
409 		/* Already streaming --- no need to check. */
410 		if (entity->pipe)
411 			continue;
412 
413 		entity->pipe = pipe;
414 
415 		if (!entity->ops || !entity->ops->link_validate)
416 			continue;
417 
418 		bitmap_zero(active, entity->num_pads);
419 		bitmap_fill(has_no_links, entity->num_pads);
420 
421 		for_each_media_entity_data_link(entity, link) {
422 			struct media_pad *pad = link->sink->entity == entity
423 						? link->sink : link->source;
424 
425 			/* Mark that a pad is connected by a link. */
426 			bitmap_clear(has_no_links, pad->index, 1);
427 
428 			/*
429 			 * Pads that either do not need to connect or
430 			 * are connected through an enabled link are
431 			 * fine.
432 			 */
433 			if (!(pad->flags & MEDIA_PAD_FL_MUST_CONNECT) ||
434 			    link->flags & MEDIA_LNK_FL_ENABLED)
435 				bitmap_set(active, pad->index, 1);
436 
437 			/*
438 			 * Link validation will only take place for
439 			 * sink ends of the link that are enabled.
440 			 */
441 			if (link->sink != pad ||
442 			    !(link->flags & MEDIA_LNK_FL_ENABLED))
443 				continue;
444 
445 			ret = entity->ops->link_validate(link);
446 			if (ret < 0 && ret != -ENOIOCTLCMD) {
447 				dev_dbg(entity->graph_obj.mdev->dev,
448 					"link validation failed for '%s':%u -> '%s':%u, error %d\n",
449 					link->source->entity->name,
450 					link->source->index,
451 					entity->name, link->sink->index, ret);
452 				goto error;
453 			}
454 		}
455 
456 		/* Either no links or validated links are fine. */
457 		bitmap_or(active, active, has_no_links, entity->num_pads);
458 
459 		if (!bitmap_full(active, entity->num_pads)) {
460 			ret = -ENOLINK;
461 			dev_dbg(entity->graph_obj.mdev->dev,
462 				"'%s':%u must be connected by an enabled link\n",
463 				entity->name,
464 				(unsigned)find_first_zero_bit(
465 					active, entity->num_pads));
466 			goto error;
467 		}
468 	}
469 
470 	pipe->start_count++;
471 
472 	return 0;
473 
474 error:
475 	/*
476 	 * Link validation on graph failed. We revert what we did and
477 	 * return the error.
478 	 */
479 	media_graph_walk_start(graph, entity_err);
480 
481 	while ((entity_err = media_graph_walk_next(graph))) {
482 		entity_err->pipe = NULL;
483 
484 		/*
485 		 * We haven't started entities further than this so we quit
486 		 * here.
487 		 */
488 		if (entity_err == entity)
489 			break;
490 	}
491 
492 	media_graph_walk_cleanup(graph);
493 
494 	return ret;
495 }
496 EXPORT_SYMBOL_GPL(__media_pipeline_start);
497 
498 __must_check int media_pipeline_start(struct media_entity *entity,
499 				      struct media_pipeline *pipe)
500 {
501 	struct media_device *mdev = entity->graph_obj.mdev;
502 	int ret;
503 
504 	mutex_lock(&mdev->graph_mutex);
505 	ret = __media_pipeline_start(entity, pipe);
506 	mutex_unlock(&mdev->graph_mutex);
507 	return ret;
508 }
509 EXPORT_SYMBOL_GPL(media_pipeline_start);
510 
511 void __media_pipeline_stop(struct media_entity *entity)
512 {
513 	struct media_graph *graph = &entity->pipe->graph;
514 	struct media_pipeline *pipe = entity->pipe;
515 
516 	/*
517 	 * If the following check fails, the driver has performed an
518 	 * unbalanced call to media_pipeline_stop()
519 	 */
520 	if (WARN_ON(!pipe))
521 		return;
522 
523 	if (--pipe->start_count)
524 		return;
525 
526 	media_graph_walk_start(graph, entity);
527 
528 	while ((entity = media_graph_walk_next(graph)))
529 		entity->pipe = NULL;
530 
531 	media_graph_walk_cleanup(graph);
532 
533 }
534 EXPORT_SYMBOL_GPL(__media_pipeline_stop);
535 
536 void media_pipeline_stop(struct media_entity *entity)
537 {
538 	struct media_device *mdev = entity->graph_obj.mdev;
539 
540 	mutex_lock(&mdev->graph_mutex);
541 	__media_pipeline_stop(entity);
542 	mutex_unlock(&mdev->graph_mutex);
543 }
544 EXPORT_SYMBOL_GPL(media_pipeline_stop);
545 
546 /* -----------------------------------------------------------------------------
547  * Links management
548  */
549 
550 static struct media_link *media_add_link(struct list_head *head)
551 {
552 	struct media_link *link;
553 
554 	link = kzalloc(sizeof(*link), GFP_KERNEL);
555 	if (link == NULL)
556 		return NULL;
557 
558 	list_add_tail(&link->list, head);
559 
560 	return link;
561 }
562 
563 static void __media_entity_remove_link(struct media_entity *entity,
564 				       struct media_link *link)
565 {
566 	struct media_link *rlink, *tmp;
567 	struct media_entity *remote;
568 
569 	/* Remove the reverse links for a data link. */
570 	if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == MEDIA_LNK_FL_DATA_LINK) {
571 		if (link->source->entity == entity)
572 			remote = link->sink->entity;
573 		else
574 			remote = link->source->entity;
575 
576 		list_for_each_entry_safe(rlink, tmp, &remote->links, list) {
577 			if (rlink != link->reverse)
578 				continue;
579 
580 			if (link->source->entity == entity)
581 				remote->num_backlinks--;
582 
583 			/* Remove the remote link */
584 			list_del(&rlink->list);
585 			media_gobj_destroy(&rlink->graph_obj);
586 			kfree(rlink);
587 
588 			if (--remote->num_links == 0)
589 				break;
590 		}
591 	}
592 
593 	list_del(&link->list);
594 	media_gobj_destroy(&link->graph_obj);
595 	kfree(link);
596 }
597 
598 int media_get_pad_index(struct media_entity *entity, bool is_sink,
599 			enum media_pad_signal_type sig_type)
600 {
601 	int i;
602 	bool pad_is_sink;
603 
604 	if (!entity)
605 		return -EINVAL;
606 
607 	for (i = 0; i < entity->num_pads; i++) {
608 		if (entity->pads[i].flags & MEDIA_PAD_FL_SINK)
609 			pad_is_sink = true;
610 		else if (entity->pads[i].flags & MEDIA_PAD_FL_SOURCE)
611 			pad_is_sink = false;
612 		else
613 			continue;	/* This is an error! */
614 
615 		if (pad_is_sink != is_sink)
616 			continue;
617 		if (entity->pads[i].sig_type == sig_type)
618 			return i;
619 	}
620 	return -EINVAL;
621 }
622 EXPORT_SYMBOL_GPL(media_get_pad_index);
623 
624 int
625 media_create_pad_link(struct media_entity *source, u16 source_pad,
626 			 struct media_entity *sink, u16 sink_pad, u32 flags)
627 {
628 	struct media_link *link;
629 	struct media_link *backlink;
630 
631 	if (WARN_ON(!source || !sink) ||
632 	    WARN_ON(source_pad >= source->num_pads) ||
633 	    WARN_ON(sink_pad >= sink->num_pads))
634 		return -EINVAL;
635 	if (WARN_ON(!(source->pads[source_pad].flags & MEDIA_PAD_FL_SOURCE)))
636 		return -EINVAL;
637 	if (WARN_ON(!(sink->pads[sink_pad].flags & MEDIA_PAD_FL_SINK)))
638 		return -EINVAL;
639 
640 	link = media_add_link(&source->links);
641 	if (link == NULL)
642 		return -ENOMEM;
643 
644 	link->source = &source->pads[source_pad];
645 	link->sink = &sink->pads[sink_pad];
646 	link->flags = flags & ~MEDIA_LNK_FL_INTERFACE_LINK;
647 
648 	/* Initialize graph object embedded at the new link */
649 	media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK,
650 			&link->graph_obj);
651 
652 	/* Create the backlink. Backlinks are used to help graph traversal and
653 	 * are not reported to userspace.
654 	 */
655 	backlink = media_add_link(&sink->links);
656 	if (backlink == NULL) {
657 		__media_entity_remove_link(source, link);
658 		return -ENOMEM;
659 	}
660 
661 	backlink->source = &source->pads[source_pad];
662 	backlink->sink = &sink->pads[sink_pad];
663 	backlink->flags = flags;
664 	backlink->is_backlink = true;
665 
666 	/* Initialize graph object embedded at the new link */
667 	media_gobj_create(sink->graph_obj.mdev, MEDIA_GRAPH_LINK,
668 			&backlink->graph_obj);
669 
670 	link->reverse = backlink;
671 	backlink->reverse = link;
672 
673 	sink->num_backlinks++;
674 	sink->num_links++;
675 	source->num_links++;
676 
677 	return 0;
678 }
679 EXPORT_SYMBOL_GPL(media_create_pad_link);
680 
681 int media_create_pad_links(const struct media_device *mdev,
682 			   const u32 source_function,
683 			   struct media_entity *source,
684 			   const u16 source_pad,
685 			   const u32 sink_function,
686 			   struct media_entity *sink,
687 			   const u16 sink_pad,
688 			   u32 flags,
689 			   const bool allow_both_undefined)
690 {
691 	struct media_entity *entity;
692 	unsigned function;
693 	int ret;
694 
695 	/* Trivial case: 1:1 relation */
696 	if (source && sink)
697 		return media_create_pad_link(source, source_pad,
698 					     sink, sink_pad, flags);
699 
700 	/* Worse case scenario: n:n relation */
701 	if (!source && !sink) {
702 		if (!allow_both_undefined)
703 			return 0;
704 		media_device_for_each_entity(source, mdev) {
705 			if (source->function != source_function)
706 				continue;
707 			media_device_for_each_entity(sink, mdev) {
708 				if (sink->function != sink_function)
709 					continue;
710 				ret = media_create_pad_link(source, source_pad,
711 							    sink, sink_pad,
712 							    flags);
713 				if (ret)
714 					return ret;
715 				flags &= ~(MEDIA_LNK_FL_ENABLED |
716 					   MEDIA_LNK_FL_IMMUTABLE);
717 			}
718 		}
719 		return 0;
720 	}
721 
722 	/* Handle 1:n and n:1 cases */
723 	if (source)
724 		function = sink_function;
725 	else
726 		function = source_function;
727 
728 	media_device_for_each_entity(entity, mdev) {
729 		if (entity->function != function)
730 			continue;
731 
732 		if (source)
733 			ret = media_create_pad_link(source, source_pad,
734 						    entity, sink_pad, flags);
735 		else
736 			ret = media_create_pad_link(entity, source_pad,
737 						    sink, sink_pad, flags);
738 		if (ret)
739 			return ret;
740 		flags &= ~(MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
741 	}
742 	return 0;
743 }
744 EXPORT_SYMBOL_GPL(media_create_pad_links);
745 
746 void __media_entity_remove_links(struct media_entity *entity)
747 {
748 	struct media_link *link, *tmp;
749 
750 	list_for_each_entry_safe(link, tmp, &entity->links, list)
751 		__media_entity_remove_link(entity, link);
752 
753 	entity->num_links = 0;
754 	entity->num_backlinks = 0;
755 }
756 EXPORT_SYMBOL_GPL(__media_entity_remove_links);
757 
758 void media_entity_remove_links(struct media_entity *entity)
759 {
760 	struct media_device *mdev = entity->graph_obj.mdev;
761 
762 	/* Do nothing if the entity is not registered. */
763 	if (mdev == NULL)
764 		return;
765 
766 	mutex_lock(&mdev->graph_mutex);
767 	__media_entity_remove_links(entity);
768 	mutex_unlock(&mdev->graph_mutex);
769 }
770 EXPORT_SYMBOL_GPL(media_entity_remove_links);
771 
772 static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
773 {
774 	int ret;
775 
776 	/* Notify both entities. */
777 	ret = media_entity_call(link->source->entity, link_setup,
778 				link->source, link->sink, flags);
779 	if (ret < 0 && ret != -ENOIOCTLCMD)
780 		return ret;
781 
782 	ret = media_entity_call(link->sink->entity, link_setup,
783 				link->sink, link->source, flags);
784 	if (ret < 0 && ret != -ENOIOCTLCMD) {
785 		media_entity_call(link->source->entity, link_setup,
786 				  link->source, link->sink, link->flags);
787 		return ret;
788 	}
789 
790 	link->flags = flags;
791 	link->reverse->flags = link->flags;
792 
793 	return 0;
794 }
795 
796 int __media_entity_setup_link(struct media_link *link, u32 flags)
797 {
798 	const u32 mask = MEDIA_LNK_FL_ENABLED;
799 	struct media_device *mdev;
800 	struct media_entity *source, *sink;
801 	int ret = -EBUSY;
802 
803 	if (link == NULL)
804 		return -EINVAL;
805 
806 	/* The non-modifiable link flags must not be modified. */
807 	if ((link->flags & ~mask) != (flags & ~mask))
808 		return -EINVAL;
809 
810 	if (link->flags & MEDIA_LNK_FL_IMMUTABLE)
811 		return link->flags == flags ? 0 : -EINVAL;
812 
813 	if (link->flags == flags)
814 		return 0;
815 
816 	source = link->source->entity;
817 	sink = link->sink->entity;
818 
819 	if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) &&
820 	    (media_entity_is_streaming(source) ||
821 	     media_entity_is_streaming(sink)))
822 		return -EBUSY;
823 
824 	mdev = source->graph_obj.mdev;
825 
826 	if (mdev->ops && mdev->ops->link_notify) {
827 		ret = mdev->ops->link_notify(link, flags,
828 					     MEDIA_DEV_NOTIFY_PRE_LINK_CH);
829 		if (ret < 0)
830 			return ret;
831 	}
832 
833 	ret = __media_entity_setup_link_notify(link, flags);
834 
835 	if (mdev->ops && mdev->ops->link_notify)
836 		mdev->ops->link_notify(link, flags,
837 				       MEDIA_DEV_NOTIFY_POST_LINK_CH);
838 
839 	return ret;
840 }
841 EXPORT_SYMBOL_GPL(__media_entity_setup_link);
842 
843 int media_entity_setup_link(struct media_link *link, u32 flags)
844 {
845 	int ret;
846 
847 	mutex_lock(&link->graph_obj.mdev->graph_mutex);
848 	ret = __media_entity_setup_link(link, flags);
849 	mutex_unlock(&link->graph_obj.mdev->graph_mutex);
850 
851 	return ret;
852 }
853 EXPORT_SYMBOL_GPL(media_entity_setup_link);
854 
855 struct media_link *
856 media_entity_find_link(struct media_pad *source, struct media_pad *sink)
857 {
858 	struct media_link *link;
859 
860 	for_each_media_entity_data_link(source->entity, link) {
861 		if (link->source->entity == source->entity &&
862 		    link->source->index == source->index &&
863 		    link->sink->entity == sink->entity &&
864 		    link->sink->index == sink->index)
865 			return link;
866 	}
867 
868 	return NULL;
869 }
870 EXPORT_SYMBOL_GPL(media_entity_find_link);
871 
872 struct media_pad *media_pad_remote_pad_first(const struct media_pad *pad)
873 {
874 	struct media_link *link;
875 
876 	for_each_media_entity_data_link(pad->entity, link) {
877 		if (!(link->flags & MEDIA_LNK_FL_ENABLED))
878 			continue;
879 
880 		if (link->source == pad)
881 			return link->sink;
882 
883 		if (link->sink == pad)
884 			return link->source;
885 	}
886 
887 	return NULL;
888 
889 }
890 EXPORT_SYMBOL_GPL(media_pad_remote_pad_first);
891 
892 struct media_pad *
893 media_entity_remote_pad_unique(const struct media_entity *entity,
894 			       unsigned int type)
895 {
896 	struct media_pad *pad = NULL;
897 	struct media_link *link;
898 
899 	list_for_each_entry(link, &entity->links, list) {
900 		struct media_pad *local_pad;
901 		struct media_pad *remote_pad;
902 
903 		if (((link->flags & MEDIA_LNK_FL_LINK_TYPE) !=
904 		     MEDIA_LNK_FL_DATA_LINK) ||
905 		    !(link->flags & MEDIA_LNK_FL_ENABLED))
906 			continue;
907 
908 		if (type == MEDIA_PAD_FL_SOURCE) {
909 			local_pad = link->sink;
910 			remote_pad = link->source;
911 		} else {
912 			local_pad = link->source;
913 			remote_pad = link->sink;
914 		}
915 
916 		if (local_pad->entity == entity) {
917 			if (pad)
918 				return ERR_PTR(-ENOTUNIQ);
919 
920 			pad = remote_pad;
921 		}
922 	}
923 
924 	if (!pad)
925 		return ERR_PTR(-ENOLINK);
926 
927 	return pad;
928 }
929 EXPORT_SYMBOL_GPL(media_entity_remote_pad_unique);
930 
931 struct media_pad *media_pad_remote_pad_unique(const struct media_pad *pad)
932 {
933 	struct media_pad *found_pad = NULL;
934 	struct media_link *link;
935 
936 	list_for_each_entry(link, &pad->entity->links, list) {
937 		struct media_pad *remote_pad;
938 
939 		if (!(link->flags & MEDIA_LNK_FL_ENABLED))
940 			continue;
941 
942 		if (link->sink == pad)
943 			remote_pad = link->source;
944 		else if (link->source == pad)
945 			remote_pad = link->sink;
946 		else
947 			continue;
948 
949 		if (found_pad)
950 			return ERR_PTR(-ENOTUNIQ);
951 
952 		found_pad = remote_pad;
953 	}
954 
955 	if (!found_pad)
956 		return ERR_PTR(-ENOLINK);
957 
958 	return found_pad;
959 }
960 EXPORT_SYMBOL_GPL(media_pad_remote_pad_unique);
961 
962 int media_entity_get_fwnode_pad(struct media_entity *entity,
963 				struct fwnode_handle *fwnode,
964 				unsigned long direction_flags)
965 {
966 	struct fwnode_endpoint endpoint;
967 	unsigned int i;
968 	int ret;
969 
970 	if (!entity->ops || !entity->ops->get_fwnode_pad) {
971 		for (i = 0; i < entity->num_pads; i++) {
972 			if (entity->pads[i].flags & direction_flags)
973 				return i;
974 		}
975 
976 		return -ENXIO;
977 	}
978 
979 	ret = fwnode_graph_parse_endpoint(fwnode, &endpoint);
980 	if (ret)
981 		return ret;
982 
983 	ret = entity->ops->get_fwnode_pad(entity, &endpoint);
984 	if (ret < 0)
985 		return ret;
986 
987 	if (ret >= entity->num_pads)
988 		return -ENXIO;
989 
990 	if (!(entity->pads[ret].flags & direction_flags))
991 		return -ENXIO;
992 
993 	return ret;
994 }
995 EXPORT_SYMBOL_GPL(media_entity_get_fwnode_pad);
996 
997 struct media_pipeline *media_entity_pipeline(struct media_entity *entity)
998 {
999 	return entity->pipe;
1000 }
1001 EXPORT_SYMBOL_GPL(media_entity_pipeline);
1002 
1003 static void media_interface_init(struct media_device *mdev,
1004 				 struct media_interface *intf,
1005 				 u32 gobj_type,
1006 				 u32 intf_type, u32 flags)
1007 {
1008 	intf->type = intf_type;
1009 	intf->flags = flags;
1010 	INIT_LIST_HEAD(&intf->links);
1011 
1012 	media_gobj_create(mdev, gobj_type, &intf->graph_obj);
1013 }
1014 
1015 /* Functions related to the media interface via device nodes */
1016 
1017 struct media_intf_devnode *media_devnode_create(struct media_device *mdev,
1018 						u32 type, u32 flags,
1019 						u32 major, u32 minor)
1020 {
1021 	struct media_intf_devnode *devnode;
1022 
1023 	devnode = kzalloc(sizeof(*devnode), GFP_KERNEL);
1024 	if (!devnode)
1025 		return NULL;
1026 
1027 	devnode->major = major;
1028 	devnode->minor = minor;
1029 
1030 	media_interface_init(mdev, &devnode->intf, MEDIA_GRAPH_INTF_DEVNODE,
1031 			     type, flags);
1032 
1033 	return devnode;
1034 }
1035 EXPORT_SYMBOL_GPL(media_devnode_create);
1036 
1037 void media_devnode_remove(struct media_intf_devnode *devnode)
1038 {
1039 	media_remove_intf_links(&devnode->intf);
1040 	media_gobj_destroy(&devnode->intf.graph_obj);
1041 	kfree(devnode);
1042 }
1043 EXPORT_SYMBOL_GPL(media_devnode_remove);
1044 
1045 struct media_link *media_create_intf_link(struct media_entity *entity,
1046 					    struct media_interface *intf,
1047 					    u32 flags)
1048 {
1049 	struct media_link *link;
1050 
1051 	link = media_add_link(&intf->links);
1052 	if (link == NULL)
1053 		return NULL;
1054 
1055 	link->intf = intf;
1056 	link->entity = entity;
1057 	link->flags = flags | MEDIA_LNK_FL_INTERFACE_LINK;
1058 
1059 	/* Initialize graph object embedded at the new link */
1060 	media_gobj_create(intf->graph_obj.mdev, MEDIA_GRAPH_LINK,
1061 			&link->graph_obj);
1062 
1063 	return link;
1064 }
1065 EXPORT_SYMBOL_GPL(media_create_intf_link);
1066 
1067 void __media_remove_intf_link(struct media_link *link)
1068 {
1069 	list_del(&link->list);
1070 	media_gobj_destroy(&link->graph_obj);
1071 	kfree(link);
1072 }
1073 EXPORT_SYMBOL_GPL(__media_remove_intf_link);
1074 
1075 void media_remove_intf_link(struct media_link *link)
1076 {
1077 	struct media_device *mdev = link->graph_obj.mdev;
1078 
1079 	/* Do nothing if the intf is not registered. */
1080 	if (mdev == NULL)
1081 		return;
1082 
1083 	mutex_lock(&mdev->graph_mutex);
1084 	__media_remove_intf_link(link);
1085 	mutex_unlock(&mdev->graph_mutex);
1086 }
1087 EXPORT_SYMBOL_GPL(media_remove_intf_link);
1088 
1089 void __media_remove_intf_links(struct media_interface *intf)
1090 {
1091 	struct media_link *link, *tmp;
1092 
1093 	list_for_each_entry_safe(link, tmp, &intf->links, list)
1094 		__media_remove_intf_link(link);
1095 
1096 }
1097 EXPORT_SYMBOL_GPL(__media_remove_intf_links);
1098 
1099 void media_remove_intf_links(struct media_interface *intf)
1100 {
1101 	struct media_device *mdev = intf->graph_obj.mdev;
1102 
1103 	/* Do nothing if the intf is not registered. */
1104 	if (mdev == NULL)
1105 		return;
1106 
1107 	mutex_lock(&mdev->graph_mutex);
1108 	__media_remove_intf_links(intf);
1109 	mutex_unlock(&mdev->graph_mutex);
1110 }
1111 EXPORT_SYMBOL_GPL(media_remove_intf_links);
1112 
1113 struct media_link *media_create_ancillary_link(struct media_entity *primary,
1114 					       struct media_entity *ancillary)
1115 {
1116 	struct media_link *link;
1117 
1118 	link = media_add_link(&primary->links);
1119 	if (!link)
1120 		return ERR_PTR(-ENOMEM);
1121 
1122 	link->gobj0 = &primary->graph_obj;
1123 	link->gobj1 = &ancillary->graph_obj;
1124 	link->flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED |
1125 		      MEDIA_LNK_FL_ANCILLARY_LINK;
1126 
1127 	/* Initialize graph object embedded in the new link */
1128 	media_gobj_create(primary->graph_obj.mdev, MEDIA_GRAPH_LINK,
1129 			  &link->graph_obj);
1130 
1131 	return link;
1132 }
1133 EXPORT_SYMBOL_GPL(media_create_ancillary_link);
1134 
1135 struct media_link *__media_entity_next_link(struct media_entity *entity,
1136 					    struct media_link *link,
1137 					    unsigned long link_type)
1138 {
1139 	link = link ? list_next_entry(link, list)
1140 		    : list_first_entry(&entity->links, typeof(*link), list);
1141 
1142 	list_for_each_entry_from(link, &entity->links, list)
1143 		if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == link_type)
1144 			return link;
1145 
1146 	return NULL;
1147 }
1148 EXPORT_SYMBOL_GPL(__media_entity_next_link);
1149