Lines Matching +full:sink +full:- +full:only
1 // SPDX-License-Identifier: GPL-2.0-only
15 #include <media/media-entity.h>
16 #include <media/media-device.h>
20 switch (intf->type) { in intf_type()
22 return "dvb-frontend"; in intf_type()
24 return "dvb-demux"; in intf_type()
26 return "dvb-dvr"; in intf_type()
28 return "dvb-ca"; in intf_type()
30 return "dvb-net"; in intf_type()
32 return "v4l-video"; in intf_type()
34 return "v4l-vbi"; in intf_type()
36 return "v4l-radio"; in intf_type()
38 return "v4l-subdev"; in intf_type()
40 return "v4l-swradio"; in intf_type()
42 return "v4l-touch"; in intf_type()
44 return "unknown-intf"; in intf_type()
50 switch (link->flags & MEDIA_LNK_FL_LINK_TYPE) { in link_type_name()
67 idx_max = ALIGN(mdev->entity_internal_idx_max + 1, BITS_PER_LONG); in media_entity_enum_init()
68 ent_enum->bmap = bitmap_zalloc(idx_max, GFP_KERNEL); in media_entity_enum_init()
69 if (!ent_enum->bmap) in media_entity_enum_init()
70 return -ENOMEM; in media_entity_enum_init()
72 ent_enum->idx_max = idx_max; in media_entity_enum_init()
80 bitmap_free(ent_enum->bmap); in media_entity_enum_cleanup()
85 * dev_dbg_obj - Prints in debug mode a change on some object
90 * Enabled only if DEBUG or CONFIG_DYNAMIC_DEBUG. Otherwise, it
98 dev_dbg(gobj->mdev->dev, in dev_dbg_obj()
101 gobj_to_entity(gobj)->name); in dev_dbg_obj()
107 dev_dbg(gobj->mdev->dev, in dev_dbg_obj()
110 media_id(link->gobj0), in dev_dbg_obj()
111 media_id(link->gobj1)); in dev_dbg_obj()
118 dev_dbg(gobj->mdev->dev, in dev_dbg_obj()
121 pad->flags & MEDIA_PAD_FL_SINK ? "sink " : "", in dev_dbg_obj()
122 pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "", in dev_dbg_obj()
123 pad->entity->name, pad->index); in dev_dbg_obj()
131 dev_dbg(gobj->mdev->dev, in dev_dbg_obj()
132 "%s id %u: intf_devnode %s - major: %d, minor: %d\n", in dev_dbg_obj()
135 devnode->major, devnode->minor); in dev_dbg_obj()
148 gobj->mdev = mdev; in media_gobj_create()
150 /* Create a per-type unique object ID */ in media_gobj_create()
151 gobj->id = media_gobj_gen_id(type, ++mdev->id); in media_gobj_create()
155 list_add_tail(&gobj->list, &mdev->entities); in media_gobj_create()
158 list_add_tail(&gobj->list, &mdev->pads); in media_gobj_create()
161 list_add_tail(&gobj->list, &mdev->links); in media_gobj_create()
164 list_add_tail(&gobj->list, &mdev->interfaces); in media_gobj_create()
168 mdev->topology_version++; in media_gobj_create()
176 if (gobj->mdev == NULL) in media_gobj_destroy()
181 gobj->mdev->topology_version++; in media_gobj_destroy()
184 list_del(&gobj->list); in media_gobj_destroy()
186 gobj->mdev = NULL; in media_gobj_destroy()
197 struct media_device *mdev = entity->graph_obj.mdev; in media_entity_pads_init()
203 return -E2BIG; in media_entity_pads_init()
205 entity->num_pads = num_pads; in media_entity_pads_init()
206 entity->pads = pads; in media_entity_pads_init()
209 mutex_lock(&mdev->graph_mutex); in media_entity_pads_init()
212 iter->entity = entity; in media_entity_pads_init()
213 iter->index = i++; in media_entity_pads_init()
215 if (hweight32(iter->flags & (MEDIA_PAD_FL_SINK | in media_entity_pads_init()
217 ret = -EINVAL; in media_entity_pads_init()
223 &iter->graph_obj); in media_entity_pads_init()
228 media_gobj_destroy(&iter->graph_obj); in media_entity_pads_init()
232 mutex_unlock(&mdev->graph_mutex); in media_entity_pads_init()
238 /* -----------------------------------------------------------------------------
243 * media_entity_has_pad_interdep - Check interdependency between two pads
259 * One of @pad0 and @pad1 must be a sink pad and the other one a source pad.
262 * The caller must hold entity->graph_obj.mdev->mutex.
269 if (pad0 >= entity->num_pads || pad1 >= entity->num_pads) in media_entity_has_pad_interdep()
272 if (entity->pads[pad0].flags & entity->pads[pad1].flags & in media_entity_has_pad_interdep()
276 if (!entity->ops || !entity->ops->has_pad_interdep) in media_entity_has_pad_interdep()
279 return entity->ops->has_pad_interdep(entity, pad0, pad1); in media_entity_has_pad_interdep()
285 if (link->source->entity == entity) in media_entity_other()
286 return link->sink->entity; in media_entity_other()
288 return link->source->entity; in media_entity_other()
295 if (graph->top == MEDIA_ENTITY_ENUM_MAX_DEPTH - 1) { in stack_push()
299 graph->top++; in stack_push()
300 graph->stack[graph->top].link = entity->links.next; in stack_push()
301 graph->stack[graph->top].entity = entity; in stack_push()
308 entity = graph->stack[graph->top].entity; in stack_pop()
309 graph->top--; in stack_pop()
314 #define link_top(en) ((en)->stack[(en)->top].link)
315 #define stack_top(en) ((en)->stack[(en)->top].entity)
318 * media_graph_walk_init - Allocate resources for graph walk
331 return media_entity_enum_init(&graph->ent_enum, mdev); in media_graph_walk_init()
336 * media_graph_walk_cleanup - Release resources related to graph walking
341 media_entity_enum_cleanup(&graph->ent_enum); in media_graph_walk_cleanup()
348 media_entity_enum_zero(&graph->ent_enum); in media_graph_walk_start()
349 media_entity_enum_set(&graph->ent_enum, entity); in media_graph_walk_start()
351 graph->top = 0; in media_graph_walk_start()
352 graph->stack[graph->top].entity = NULL; in media_graph_walk_start()
354 dev_dbg(entity->graph_obj.mdev->dev, in media_graph_walk_start()
355 "begin graph walk at '%s'\n", entity->name); in media_graph_walk_start()
368 if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) != MEDIA_LNK_FL_DATA_LINK) { in media_graph_walk_iter()
369 link_top(graph) = link_top(graph)->next; in media_graph_walk_iter()
374 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { in media_graph_walk_iter()
375 link_top(graph) = link_top(graph)->next; in media_graph_walk_iter()
376 dev_dbg(entity->graph_obj.mdev->dev, in media_graph_walk_iter()
377 "walk: skipping disabled link '%s':%u -> '%s':%u\n", in media_graph_walk_iter()
378 link->source->entity->name, link->source->index, in media_graph_walk_iter()
379 link->sink->entity->name, link->sink->index); in media_graph_walk_iter()
387 if (media_entity_enum_test_and_set(&graph->ent_enum, next)) { in media_graph_walk_iter()
388 link_top(graph) = link_top(graph)->next; in media_graph_walk_iter()
389 dev_dbg(entity->graph_obj.mdev->dev, in media_graph_walk_iter()
391 next->name); in media_graph_walk_iter()
396 link_top(graph) = link_top(graph)->next; in media_graph_walk_iter()
398 dev_dbg(entity->graph_obj.mdev->dev, "walk: pushing '%s' on stack\n", in media_graph_walk_iter()
399 next->name); in media_graph_walk_iter()
400 lockdep_assert_held(&entity->graph_obj.mdev->graph_mutex); in media_graph_walk_iter()
415 while (link_top(graph) != &stack_top(graph)->links) in media_graph_walk_next()
419 dev_dbg(entity->graph_obj.mdev->dev, in media_graph_walk_next()
420 "walk: returning entity '%s'\n", entity->name); in media_graph_walk_next()
426 /* -----------------------------------------------------------------------------
444 * struct media_pipeline_walk_entry - Entry in the pipeline traversal stack
455 * struct media_pipeline_walk - State used by the media pipeline traversal
459 * @stack: Depth-first search stack
461 * @stack.top: Index of the top stack entry (-1 if the stack is empty)
479 return &walk->stack.entries[walk->stack.top]; in media_pipeline_walk_top()
484 return walk->stack.top == -1; in media_pipeline_walk_empty()
494 if (walk->stack.size >= 256) in media_pipeline_walk_resize()
495 return -E2BIG; in media_pipeline_walk_resize()
497 new_size = walk->stack.size + MEDIA_PIPELINE_STACK_GROW_STEP; in media_pipeline_walk_resize()
499 entries = krealloc(walk->stack.entries, in media_pipeline_walk_resize()
500 new_size * sizeof(*walk->stack.entries), in media_pipeline_walk_resize()
503 return -ENOMEM; in media_pipeline_walk_resize()
505 walk->stack.entries = entries; in media_pipeline_walk_resize()
506 walk->stack.size = new_size; in media_pipeline_walk_resize()
518 if (walk->stack.top + 1 >= walk->stack.size) { in media_pipeline_walk_push()
524 walk->stack.top++; in media_pipeline_walk_push()
526 entry->pad = pad; in media_pipeline_walk_push()
527 entry->links = pad->entity->links.next; in media_pipeline_walk_push()
529 dev_dbg(walk->mdev->dev, in media_pipeline_walk_push()
531 walk->stack.top, pad->entity->name, pad->index); in media_pipeline_walk_push()
545 if (WARN_ON(walk->stack.top < 0)) in media_pipeline_walk_pop()
550 if (entry->links->next == &entry->pad->entity->links) { in media_pipeline_walk_pop()
551 dev_dbg(walk->mdev->dev, in media_pipeline_walk_pop()
553 walk->stack.top); in media_pipeline_walk_pop()
555 walk->stack.top--; in media_pipeline_walk_pop()
559 entry->links = entry->links->next; in media_pipeline_walk_pop()
561 dev_dbg(walk->mdev->dev, in media_pipeline_walk_pop()
563 walk->stack.top); in media_pipeline_walk_pop()
571 kfree(walk->stack.entries); in media_pipeline_walk_destroy()
581 list_for_each_entry(ppad, &pipe->pads, list) { in media_pipeline_add_pad()
582 if (ppad->pad == pad) { in media_pipeline_add_pad()
583 dev_dbg(pad->graph_obj.mdev->dev, in media_pipeline_add_pad()
585 pad->entity->name, pad->index); in media_pipeline_add_pad()
592 return -ENOMEM; in media_pipeline_add_pad()
594 ppad->pipe = pipe; in media_pipeline_add_pad()
595 ppad->pad = pad; in media_pipeline_add_pad()
597 list_add_tail(&ppad->list, &pipe->pads); in media_pipeline_add_pad()
599 dev_dbg(pad->graph_obj.mdev->dev, in media_pipeline_add_pad()
601 pad->entity->name, pad->index); in media_pipeline_add_pad()
618 origin = entry->pad; in media_pipeline_explore_next_link()
619 link = list_entry(entry->links, typeof(*link), list); in media_pipeline_explore_next_link()
622 if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) != MEDIA_LNK_FL_DATA_LINK) { in media_pipeline_explore_next_link()
623 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
624 "media pipeline: skipping link (not data-link)\n"); in media_pipeline_explore_next_link()
628 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
629 "media pipeline: exploring link '%s':%u -> '%s':%u\n", in media_pipeline_explore_next_link()
630 link->source->entity->name, link->source->index, in media_pipeline_explore_next_link()
631 link->sink->entity->name, link->sink->index); in media_pipeline_explore_next_link()
634 if (link->source->entity == origin->entity) { in media_pipeline_explore_next_link()
635 local = link->source; in media_pipeline_explore_next_link()
636 remote = link->sink; in media_pipeline_explore_next_link()
638 local = link->sink; in media_pipeline_explore_next_link()
639 remote = link->source; in media_pipeline_explore_next_link()
647 !media_entity_has_pad_interdep(origin->entity, origin->index, in media_pipeline_explore_next_link()
648 local->index)) { in media_pipeline_explore_next_link()
649 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
662 /* Similarly, add the remote pad, but only if the link is enabled. */ in media_pipeline_explore_next_link()
663 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { in media_pipeline_explore_next_link()
664 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
684 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
686 local->entity->name); in media_pipeline_explore_next_link()
688 media_entity_for_each_pad(origin->entity, local) { in media_pipeline_explore_next_link()
694 if (origin == local || !local->num_links || in media_pipeline_explore_next_link()
695 !media_entity_has_pad_interdep(origin->entity, origin->index, in media_pipeline_explore_next_link()
696 local->index)) in media_pipeline_explore_next_link()
709 while (!list_empty(&pipe->pads)) { in media_pipeline_cleanup()
712 ppad = list_first_entry(&pipe->pads, typeof(*ppad), list); in media_pipeline_cleanup()
713 list_del(&ppad->list); in media_pipeline_cleanup()
729 INIT_LIST_HEAD(&pipe->pads); in media_pipeline_populate()
730 pipe->mdev = pad->graph_obj.mdev; in media_pipeline_populate()
732 walk.mdev = pipe->mdev; in media_pipeline_populate()
733 walk.stack.top = -1; in media_pipeline_populate()
739 * Use a depth-first search algorithm: as long as the stack is not in media_pipeline_populate()
751 dev_dbg(pad->graph_obj.mdev->dev, in media_pipeline_populate()
754 list_for_each_entry(ppad, &pipe->pads, list) in media_pipeline_populate()
755 dev_dbg(pad->graph_obj.mdev->dev, "- '%s':%u\n", in media_pipeline_populate()
756 ppad->pad->entity->name, ppad->pad->index); in media_pipeline_populate()
758 WARN_ON(walk.stack.top != -1); in media_pipeline_populate()
774 struct media_device *mdev = origin->graph_obj.mdev; in __media_pipeline_start()
779 lockdep_assert_held(&mdev->graph_mutex); in __media_pipeline_start()
785 if (WARN_ON(origin->pipe && origin->pipe != pipe)) in __media_pipeline_start()
786 return -EINVAL; in __media_pipeline_start()
792 if (pipe->start_count) { in __media_pipeline_start()
793 pipe->start_count++; in __media_pipeline_start()
811 list_for_each_entry(ppad, &pipe->pads, list) { in __media_pipeline_start()
812 struct media_pad *pad = ppad->pad; in __media_pipeline_start()
813 struct media_entity *entity = pad->entity; in __media_pipeline_start()
817 dev_dbg(mdev->dev, "Validating pad '%s':%u\n", pad->entity->name, in __media_pipeline_start()
818 pad->index); in __media_pipeline_start()
824 if (pad->pipe) { in __media_pipeline_start()
825 dev_dbg(mdev->dev, "Failed to start pipeline: pad '%s':%u busy\n", in __media_pipeline_start()
826 pad->entity->name, pad->index); in __media_pipeline_start()
827 ret = -EBUSY; in __media_pipeline_start()
832 * 2. Validate all active links whose sink is the current pad. in __media_pipeline_start()
834 * the connected sink pad to avoid duplicating checks. in __media_pipeline_start()
838 if (link->sink != pad && link->source != pad) in __media_pipeline_start()
842 if (link->flags & MEDIA_LNK_FL_ENABLED) in __media_pipeline_start()
847 * current pad as its sink. in __media_pipeline_start()
849 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) in __media_pipeline_start()
852 if (link->sink != pad) in __media_pipeline_start()
855 if (!entity->ops || !entity->ops->link_validate) in __media_pipeline_start()
858 ret = entity->ops->link_validate(link); in __media_pipeline_start()
860 dev_dbg(mdev->dev, in __media_pipeline_start()
861 "Link '%s':%u -> '%s':%u failed validation: %d\n", in __media_pipeline_start()
862 link->source->entity->name, in __media_pipeline_start()
863 link->source->index, in __media_pipeline_start()
864 link->sink->entity->name, in __media_pipeline_start()
865 link->sink->index, ret); in __media_pipeline_start()
869 dev_dbg(mdev->dev, in __media_pipeline_start()
870 "Link '%s':%u -> '%s':%u is valid\n", in __media_pipeline_start()
871 link->source->entity->name, in __media_pipeline_start()
872 link->source->index, in __media_pipeline_start()
873 link->sink->entity->name, in __media_pipeline_start()
874 link->sink->index); in __media_pipeline_start()
881 if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) && in __media_pipeline_start()
883 dev_dbg(mdev->dev, in __media_pipeline_start()
885 pad->entity->name, pad->index); in __media_pipeline_start()
886 ret = -ENOLINK; in __media_pipeline_start()
891 pad->pipe = pipe; in __media_pipeline_start()
894 pipe->start_count++; in __media_pipeline_start()
904 list_for_each_entry(err_ppad, &pipe->pads, list) { in __media_pipeline_start()
908 err_ppad->pad->pipe = NULL; in __media_pipeline_start()
920 struct media_device *mdev = origin->graph_obj.mdev; in media_pipeline_start()
923 mutex_lock(&mdev->graph_mutex); in media_pipeline_start()
925 mutex_unlock(&mdev->graph_mutex); in media_pipeline_start()
932 struct media_pipeline *pipe = pad->pipe; in __media_pipeline_stop()
942 if (--pipe->start_count) in __media_pipeline_stop()
945 list_for_each_entry(ppad, &pipe->pads, list) in __media_pipeline_stop()
946 ppad->pad->pipe = NULL; in __media_pipeline_stop()
950 if (pipe->allocated) in __media_pipeline_stop()
957 struct media_device *mdev = pad->graph_obj.mdev; in media_pipeline_stop()
959 mutex_lock(&mdev->graph_mutex); in media_pipeline_stop()
961 mutex_unlock(&mdev->graph_mutex); in media_pipeline_stop()
967 struct media_device *mdev = pad->graph_obj.mdev; in media_pipeline_alloc_start()
972 mutex_lock(&mdev->graph_mutex); in media_pipeline_alloc_start()
982 ret = -ENOMEM; in media_pipeline_alloc_start()
987 pipe->allocated = true; in media_pipeline_alloc_start()
995 mutex_unlock(&mdev->graph_mutex); in media_pipeline_alloc_start()
1007 iter->cursor = pipe->pads.next; in __media_pipeline_pad_iter_next()
1009 if (iter->cursor == &pipe->pads) in __media_pipeline_pad_iter_next()
1012 pad = list_entry(iter->cursor, struct media_pipeline_pad, list)->pad; in __media_pipeline_pad_iter_next()
1013 iter->cursor = iter->cursor->next; in __media_pipeline_pad_iter_next()
1022 return media_entity_enum_init(&iter->ent_enum, pipe->mdev); in media_pipeline_entity_iter_init()
1028 media_entity_enum_cleanup(&iter->ent_enum); in media_pipeline_entity_iter_cleanup()
1038 iter->cursor = pipe->pads.next; in __media_pipeline_entity_iter_next()
1040 while (iter->cursor != &pipe->pads) { in __media_pipeline_entity_iter_next()
1044 ppad = list_entry(iter->cursor, struct media_pipeline_pad, list); in __media_pipeline_entity_iter_next()
1045 entity = ppad->pad->entity; in __media_pipeline_entity_iter_next()
1046 iter->cursor = iter->cursor->next; in __media_pipeline_entity_iter_next()
1048 if (!media_entity_enum_test_and_set(&iter->ent_enum, entity)) in __media_pipeline_entity_iter_next()
1056 /* -----------------------------------------------------------------------------
1068 list_add_tail(&link->list, head); in media_add_link()
1080 if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == MEDIA_LNK_FL_DATA_LINK) { in __media_entity_remove_link()
1081 link->source->num_links--; in __media_entity_remove_link()
1082 link->sink->num_links--; in __media_entity_remove_link()
1084 if (link->source->entity == entity) in __media_entity_remove_link()
1085 remote = link->sink->entity; in __media_entity_remove_link()
1087 remote = link->source->entity; in __media_entity_remove_link()
1089 list_for_each_entry_safe(rlink, tmp, &remote->links, list) { in __media_entity_remove_link()
1090 if (rlink != link->reverse) in __media_entity_remove_link()
1093 if (link->source->entity == entity) in __media_entity_remove_link()
1094 remote->num_backlinks--; in __media_entity_remove_link()
1097 list_del(&rlink->list); in __media_entity_remove_link()
1098 media_gobj_destroy(&rlink->graph_obj); in __media_entity_remove_link()
1101 if (--remote->num_links == 0) in __media_entity_remove_link()
1106 list_del(&link->list); in __media_entity_remove_link()
1107 media_gobj_destroy(&link->graph_obj); in __media_entity_remove_link()
1117 return -EINVAL; in media_get_pad_index()
1119 for (i = 0; i < entity->num_pads; i++) { in media_get_pad_index()
1120 if ((entity->pads[i].flags & in media_get_pad_index()
1124 if (entity->pads[i].sig_type == sig_type) in media_get_pad_index()
1127 return -EINVAL; in media_get_pad_index()
1133 struct media_entity *sink, u16 sink_pad, u32 flags) in media_create_pad_link() argument
1139 return -EINVAL; in media_create_pad_link()
1143 if (WARN_ON(!source || !sink) || in media_create_pad_link()
1144 WARN_ON(source_pad >= source->num_pads) || in media_create_pad_link()
1145 WARN_ON(sink_pad >= sink->num_pads)) in media_create_pad_link()
1146 return -EINVAL; in media_create_pad_link()
1147 if (WARN_ON(!(source->pads[source_pad].flags & MEDIA_PAD_FL_SOURCE))) in media_create_pad_link()
1148 return -EINVAL; in media_create_pad_link()
1149 if (WARN_ON(!(sink->pads[sink_pad].flags & MEDIA_PAD_FL_SINK))) in media_create_pad_link()
1150 return -EINVAL; in media_create_pad_link()
1152 link = media_add_link(&source->links); in media_create_pad_link()
1154 return -ENOMEM; in media_create_pad_link()
1156 link->source = &source->pads[source_pad]; in media_create_pad_link()
1157 link->sink = &sink->pads[sink_pad]; in media_create_pad_link()
1158 link->flags = flags; in media_create_pad_link()
1161 media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK, in media_create_pad_link()
1162 &link->graph_obj); in media_create_pad_link()
1167 backlink = media_add_link(&sink->links); in media_create_pad_link()
1170 return -ENOMEM; in media_create_pad_link()
1173 backlink->source = &source->pads[source_pad]; in media_create_pad_link()
1174 backlink->sink = &sink->pads[sink_pad]; in media_create_pad_link()
1175 backlink->flags = flags; in media_create_pad_link()
1176 backlink->is_backlink = true; in media_create_pad_link()
1179 media_gobj_create(sink->graph_obj.mdev, MEDIA_GRAPH_LINK, in media_create_pad_link()
1180 &backlink->graph_obj); in media_create_pad_link()
1182 link->reverse = backlink; in media_create_pad_link()
1183 backlink->reverse = link; in media_create_pad_link()
1185 sink->num_backlinks++; in media_create_pad_link()
1186 sink->num_links++; in media_create_pad_link()
1187 source->num_links++; in media_create_pad_link()
1189 link->source->num_links++; in media_create_pad_link()
1190 link->sink->num_links++; in media_create_pad_link()
1201 struct media_entity *sink, in media_create_pad_links() argument
1211 if (source && sink) in media_create_pad_links()
1213 sink, sink_pad, flags); in media_create_pad_links()
1216 if (!source && !sink) { in media_create_pad_links()
1220 if (source->function != source_function) in media_create_pad_links()
1222 media_device_for_each_entity(sink, mdev) { in media_create_pad_links()
1223 if (sink->function != sink_function) in media_create_pad_links()
1226 sink, sink_pad, in media_create_pad_links()
1244 if (entity->function != function) in media_create_pad_links()
1252 sink, sink_pad, flags); in media_create_pad_links()
1265 list_for_each_entry_safe(link, tmp, &entity->links, list) in __media_entity_remove_links()
1268 entity->num_links = 0; in __media_entity_remove_links()
1269 entity->num_backlinks = 0; in __media_entity_remove_links()
1275 struct media_device *mdev = entity->graph_obj.mdev; in media_entity_remove_links()
1281 mutex_lock(&mdev->graph_mutex); in media_entity_remove_links()
1283 mutex_unlock(&mdev->graph_mutex); in media_entity_remove_links()
1292 ret = media_entity_call(link->source->entity, link_setup, in __media_entity_setup_link_notify()
1293 link->source, link->sink, flags); in __media_entity_setup_link_notify()
1294 if (ret < 0 && ret != -ENOIOCTLCMD) in __media_entity_setup_link_notify()
1297 ret = media_entity_call(link->sink->entity, link_setup, in __media_entity_setup_link_notify()
1298 link->sink, link->source, flags); in __media_entity_setup_link_notify()
1299 if (ret < 0 && ret != -ENOIOCTLCMD) { in __media_entity_setup_link_notify()
1300 media_entity_call(link->source->entity, link_setup, in __media_entity_setup_link_notify()
1301 link->source, link->sink, link->flags); in __media_entity_setup_link_notify()
1305 link->flags = flags; in __media_entity_setup_link_notify()
1306 link->reverse->flags = link->flags; in __media_entity_setup_link_notify()
1315 struct media_pad *source, *sink; in __media_entity_setup_link() local
1316 int ret = -EBUSY; in __media_entity_setup_link()
1319 return -EINVAL; in __media_entity_setup_link()
1321 /* The non-modifiable link flags must not be modified. */ in __media_entity_setup_link()
1322 if ((link->flags & ~mask) != (flags & ~mask)) in __media_entity_setup_link()
1323 return -EINVAL; in __media_entity_setup_link()
1325 if (link->flags & MEDIA_LNK_FL_IMMUTABLE) in __media_entity_setup_link()
1326 return link->flags == flags ? 0 : -EINVAL; in __media_entity_setup_link()
1328 if (link->flags == flags) in __media_entity_setup_link()
1331 source = link->source; in __media_entity_setup_link()
1332 sink = link->sink; in __media_entity_setup_link()
1334 if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) && in __media_entity_setup_link()
1335 (media_pad_is_streaming(source) || media_pad_is_streaming(sink))) in __media_entity_setup_link()
1336 return -EBUSY; in __media_entity_setup_link()
1338 mdev = source->graph_obj.mdev; in __media_entity_setup_link()
1340 if (mdev->ops && mdev->ops->link_notify) { in __media_entity_setup_link()
1341 ret = mdev->ops->link_notify(link, flags, in __media_entity_setup_link()
1349 if (mdev->ops && mdev->ops->link_notify) in __media_entity_setup_link()
1350 mdev->ops->link_notify(link, flags, in __media_entity_setup_link()
1361 mutex_lock(&link->graph_obj.mdev->graph_mutex); in media_entity_setup_link()
1363 mutex_unlock(&link->graph_obj.mdev->graph_mutex); in media_entity_setup_link()
1370 media_entity_find_link(struct media_pad *source, struct media_pad *sink) in media_entity_find_link() argument
1374 for_each_media_entity_data_link(source->entity, link) { in media_entity_find_link()
1375 if (link->source->entity == source->entity && in media_entity_find_link()
1376 link->source->index == source->index && in media_entity_find_link()
1377 link->sink->entity == sink->entity && in media_entity_find_link()
1378 link->sink->index == sink->index) in media_entity_find_link()
1390 for_each_media_entity_data_link(pad->entity, link) { in media_pad_remote_pad_first()
1391 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) in media_pad_remote_pad_first()
1394 if (link->source == pad) in media_pad_remote_pad_first()
1395 return link->sink; in media_pad_remote_pad_first()
1397 if (link->sink == pad) in media_pad_remote_pad_first()
1398 return link->source; in media_pad_remote_pad_first()
1413 list_for_each_entry(link, &entity->links, list) { in media_entity_remote_pad_unique()
1417 if (((link->flags & MEDIA_LNK_FL_LINK_TYPE) != in media_entity_remote_pad_unique()
1419 !(link->flags & MEDIA_LNK_FL_ENABLED)) in media_entity_remote_pad_unique()
1423 local_pad = link->sink; in media_entity_remote_pad_unique()
1424 remote_pad = link->source; in media_entity_remote_pad_unique()
1426 local_pad = link->source; in media_entity_remote_pad_unique()
1427 remote_pad = link->sink; in media_entity_remote_pad_unique()
1430 if (local_pad->entity == entity) { in media_entity_remote_pad_unique()
1432 return ERR_PTR(-ENOTUNIQ); in media_entity_remote_pad_unique()
1439 return ERR_PTR(-ENOLINK); in media_entity_remote_pad_unique()
1450 list_for_each_entry(link, &pad->entity->links, list) { in media_pad_remote_pad_unique()
1453 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) in media_pad_remote_pad_unique()
1456 if (link->sink == pad) in media_pad_remote_pad_unique()
1457 remote_pad = link->source; in media_pad_remote_pad_unique()
1458 else if (link->source == pad) in media_pad_remote_pad_unique()
1459 remote_pad = link->sink; in media_pad_remote_pad_unique()
1464 return ERR_PTR(-ENOTUNIQ); in media_pad_remote_pad_unique()
1470 return ERR_PTR(-ENOLINK); in media_pad_remote_pad_unique()
1484 if (!entity->ops || !entity->ops->get_fwnode_pad) { in media_entity_get_fwnode_pad()
1485 for (i = 0; i < entity->num_pads; i++) { in media_entity_get_fwnode_pad()
1486 if (entity->pads[i].flags & direction_flags) in media_entity_get_fwnode_pad()
1490 return -ENXIO; in media_entity_get_fwnode_pad()
1497 ret = entity->ops->get_fwnode_pad(entity, &endpoint); in media_entity_get_fwnode_pad()
1501 if (ret >= entity->num_pads) in media_entity_get_fwnode_pad()
1502 return -ENXIO; in media_entity_get_fwnode_pad()
1504 if (!(entity->pads[ret].flags & direction_flags)) in media_entity_get_fwnode_pad()
1505 return -ENXIO; in media_entity_get_fwnode_pad()
1516 if (pad->pipe) in media_entity_pipeline()
1517 return pad->pipe; in media_entity_pipeline()
1526 return pad->pipe; in media_pad_pipeline()
1535 intf->type = intf_type; in media_interface_init()
1536 intf->flags = flags; in media_interface_init()
1537 INIT_LIST_HEAD(&intf->links); in media_interface_init()
1539 media_gobj_create(mdev, gobj_type, &intf->graph_obj); in media_interface_init()
1554 devnode->major = major; in media_devnode_create()
1555 devnode->minor = minor; in media_devnode_create()
1557 media_interface_init(mdev, &devnode->intf, MEDIA_GRAPH_INTF_DEVNODE, in media_devnode_create()
1566 media_remove_intf_links(&devnode->intf); in media_devnode_remove()
1567 media_gobj_destroy(&devnode->intf.graph_obj); in media_devnode_remove()
1578 link = media_add_link(&intf->links); in media_create_intf_link()
1582 link->intf = intf; in media_create_intf_link()
1583 link->entity = entity; in media_create_intf_link()
1584 link->flags = flags | MEDIA_LNK_FL_INTERFACE_LINK; in media_create_intf_link()
1587 media_gobj_create(intf->graph_obj.mdev, MEDIA_GRAPH_LINK, in media_create_intf_link()
1588 &link->graph_obj); in media_create_intf_link()
1596 list_del(&link->list); in __media_remove_intf_link()
1597 media_gobj_destroy(&link->graph_obj); in __media_remove_intf_link()
1604 struct media_device *mdev = link->graph_obj.mdev; in media_remove_intf_link()
1610 mutex_lock(&mdev->graph_mutex); in media_remove_intf_link()
1612 mutex_unlock(&mdev->graph_mutex); in media_remove_intf_link()
1620 list_for_each_entry_safe(link, tmp, &intf->links, list) in __media_remove_intf_links()
1628 struct media_device *mdev = intf->graph_obj.mdev; in media_remove_intf_links()
1634 mutex_lock(&mdev->graph_mutex); in media_remove_intf_links()
1636 mutex_unlock(&mdev->graph_mutex); in media_remove_intf_links()
1645 link = media_add_link(&primary->links); in media_create_ancillary_link()
1647 return ERR_PTR(-ENOMEM); in media_create_ancillary_link()
1649 link->gobj0 = &primary->graph_obj; in media_create_ancillary_link()
1650 link->gobj1 = &ancillary->graph_obj; in media_create_ancillary_link()
1651 link->flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED | in media_create_ancillary_link()
1655 media_gobj_create(primary->graph_obj.mdev, MEDIA_GRAPH_LINK, in media_create_ancillary_link()
1656 &link->graph_obj); in media_create_ancillary_link()
1667 : list_first_entry(&entity->links, typeof(*link), list); in __media_entity_next_link()
1669 list_for_each_entry_from(link, &entity->links, list) in __media_entity_next_link()
1670 if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == link_type) in __media_entity_next_link()