• Home
  • Raw
  • Download

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()
202 return -E2BIG; in media_entity_pads_init()
204 entity->num_pads = num_pads; in media_entity_pads_init()
205 entity->pads = pads; in media_entity_pads_init()
208 mutex_lock(&mdev->graph_mutex); in media_entity_pads_init()
211 iter->entity = entity; in media_entity_pads_init()
212 iter->index = i++; in media_entity_pads_init()
215 &iter->graph_obj); in media_entity_pads_init()
219 mutex_unlock(&mdev->graph_mutex); in media_entity_pads_init()
225 /* -----------------------------------------------------------------------------
230 * media_entity_has_pad_interdep - Check interdependency between two pads
246 * One of @pad0 and @pad1 must be a sink pad and the other one a source pad.
249 * The caller must hold entity->graph_obj.mdev->mutex.
256 if (pad0 >= entity->num_pads || pad1 >= entity->num_pads) in media_entity_has_pad_interdep()
259 if (entity->pads[pad0].flags & entity->pads[pad1].flags & in media_entity_has_pad_interdep()
263 if (!entity->ops || !entity->ops->has_pad_interdep) in media_entity_has_pad_interdep()
266 return entity->ops->has_pad_interdep(entity, pad0, pad1); in media_entity_has_pad_interdep()
272 if (link->source->entity == entity) in media_entity_other()
273 return link->sink->entity; in media_entity_other()
275 return link->source->entity; in media_entity_other()
282 if (graph->top == MEDIA_ENTITY_ENUM_MAX_DEPTH - 1) { in stack_push()
286 graph->top++; in stack_push()
287 graph->stack[graph->top].link = entity->links.next; in stack_push()
288 graph->stack[graph->top].entity = entity; in stack_push()
295 entity = graph->stack[graph->top].entity; in stack_pop()
296 graph->top--; in stack_pop()
301 #define link_top(en) ((en)->stack[(en)->top].link)
302 #define stack_top(en) ((en)->stack[(en)->top].entity)
305 * media_graph_walk_init - Allocate resources for graph walk
318 return media_entity_enum_init(&graph->ent_enum, mdev); in media_graph_walk_init()
323 * media_graph_walk_cleanup - Release resources related to graph walking
328 media_entity_enum_cleanup(&graph->ent_enum); in media_graph_walk_cleanup()
335 media_entity_enum_zero(&graph->ent_enum); in media_graph_walk_start()
336 media_entity_enum_set(&graph->ent_enum, entity); in media_graph_walk_start()
338 graph->top = 0; in media_graph_walk_start()
339 graph->stack[graph->top].entity = NULL; in media_graph_walk_start()
341 dev_dbg(entity->graph_obj.mdev->dev, in media_graph_walk_start()
342 "begin graph walk at '%s'\n", entity->name); in media_graph_walk_start()
355 if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) != MEDIA_LNK_FL_DATA_LINK) { in media_graph_walk_iter()
356 link_top(graph) = link_top(graph)->next; in media_graph_walk_iter()
361 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { in media_graph_walk_iter()
362 link_top(graph) = link_top(graph)->next; in media_graph_walk_iter()
363 dev_dbg(entity->graph_obj.mdev->dev, in media_graph_walk_iter()
364 "walk: skipping disabled link '%s':%u -> '%s':%u\n", in media_graph_walk_iter()
365 link->source->entity->name, link->source->index, in media_graph_walk_iter()
366 link->sink->entity->name, link->sink->index); in media_graph_walk_iter()
374 if (media_entity_enum_test_and_set(&graph->ent_enum, next)) { 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()
378 next->name); in media_graph_walk_iter()
383 link_top(graph) = link_top(graph)->next; in media_graph_walk_iter()
385 dev_dbg(entity->graph_obj.mdev->dev, "walk: pushing '%s' on stack\n", in media_graph_walk_iter()
386 next->name); in media_graph_walk_iter()
387 lockdep_assert_held(&entity->graph_obj.mdev->graph_mutex); in media_graph_walk_iter()
402 while (link_top(graph) != &stack_top(graph)->links) in media_graph_walk_next()
406 dev_dbg(entity->graph_obj.mdev->dev, in media_graph_walk_next()
407 "walk: returning entity '%s'\n", entity->name); in media_graph_walk_next()
413 /* -----------------------------------------------------------------------------
431 * struct media_pipeline_walk_entry - Entry in the pipeline traversal stack
442 * struct media_pipeline_walk - State used by the media pipeline traversal
446 * @stack: Depth-first search stack
448 * @stack.top: Index of the top stack entry (-1 if the stack is empty)
466 return &walk->stack.entries[walk->stack.top]; in media_pipeline_walk_top()
471 return walk->stack.top == -1; in media_pipeline_walk_empty()
481 if (walk->stack.size >= 256) in media_pipeline_walk_resize()
482 return -E2BIG; in media_pipeline_walk_resize()
484 new_size = walk->stack.size + MEDIA_PIPELINE_STACK_GROW_STEP; in media_pipeline_walk_resize()
486 entries = krealloc(walk->stack.entries, in media_pipeline_walk_resize()
487 new_size * sizeof(*walk->stack.entries), in media_pipeline_walk_resize()
490 return -ENOMEM; in media_pipeline_walk_resize()
492 walk->stack.entries = entries; in media_pipeline_walk_resize()
493 walk->stack.size = new_size; in media_pipeline_walk_resize()
505 if (walk->stack.top + 1 >= walk->stack.size) { in media_pipeline_walk_push()
511 walk->stack.top++; in media_pipeline_walk_push()
513 entry->pad = pad; in media_pipeline_walk_push()
514 entry->links = pad->entity->links.next; in media_pipeline_walk_push()
516 dev_dbg(walk->mdev->dev, in media_pipeline_walk_push()
518 walk->stack.top, pad->entity->name, pad->index); in media_pipeline_walk_push()
532 if (WARN_ON(walk->stack.top < 0)) in media_pipeline_walk_pop()
537 if (entry->links->next == &entry->pad->entity->links) { in media_pipeline_walk_pop()
538 dev_dbg(walk->mdev->dev, in media_pipeline_walk_pop()
540 walk->stack.top); in media_pipeline_walk_pop()
542 walk->stack.top--; in media_pipeline_walk_pop()
546 entry->links = entry->links->next; in media_pipeline_walk_pop()
548 dev_dbg(walk->mdev->dev, in media_pipeline_walk_pop()
550 walk->stack.top); in media_pipeline_walk_pop()
558 kfree(walk->stack.entries); in media_pipeline_walk_destroy()
568 list_for_each_entry(ppad, &pipe->pads, list) { in media_pipeline_add_pad()
569 if (ppad->pad == pad) { in media_pipeline_add_pad()
570 dev_dbg(pad->graph_obj.mdev->dev, in media_pipeline_add_pad()
572 pad->entity->name, pad->index); in media_pipeline_add_pad()
579 return -ENOMEM; in media_pipeline_add_pad()
581 ppad->pipe = pipe; in media_pipeline_add_pad()
582 ppad->pad = pad; in media_pipeline_add_pad()
584 list_add_tail(&ppad->list, &pipe->pads); in media_pipeline_add_pad()
586 dev_dbg(pad->graph_obj.mdev->dev, in media_pipeline_add_pad()
588 pad->entity->name, pad->index); in media_pipeline_add_pad()
605 origin = entry->pad; in media_pipeline_explore_next_link()
606 link = list_entry(entry->links, typeof(*link), list); in media_pipeline_explore_next_link()
609 if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) != MEDIA_LNK_FL_DATA_LINK) { in media_pipeline_explore_next_link()
610 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
611 "media pipeline: skipping link (not data-link)\n"); in media_pipeline_explore_next_link()
615 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
616 "media pipeline: exploring link '%s':%u -> '%s':%u\n", in media_pipeline_explore_next_link()
617 link->source->entity->name, link->source->index, in media_pipeline_explore_next_link()
618 link->sink->entity->name, link->sink->index); in media_pipeline_explore_next_link()
621 if (link->source->entity == origin->entity) { in media_pipeline_explore_next_link()
622 local = link->source; in media_pipeline_explore_next_link()
623 remote = link->sink; in media_pipeline_explore_next_link()
625 local = link->sink; in media_pipeline_explore_next_link()
626 remote = link->source; in media_pipeline_explore_next_link()
634 !media_entity_has_pad_interdep(origin->entity, origin->index, in media_pipeline_explore_next_link()
635 local->index)) { in media_pipeline_explore_next_link()
636 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
649 /* Similarly, add the remote pad, but only if the link is enabled. */ in media_pipeline_explore_next_link()
650 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { in media_pipeline_explore_next_link()
651 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
671 dev_dbg(walk->mdev->dev, in media_pipeline_explore_next_link()
673 local->entity->name); in media_pipeline_explore_next_link()
675 media_entity_for_each_pad(origin->entity, local) { in media_pipeline_explore_next_link()
681 if (origin == local || !local->num_links || in media_pipeline_explore_next_link()
682 !media_entity_has_pad_interdep(origin->entity, origin->index, in media_pipeline_explore_next_link()
683 local->index)) in media_pipeline_explore_next_link()
696 while (!list_empty(&pipe->pads)) { in media_pipeline_cleanup()
699 ppad = list_first_entry(&pipe->pads, typeof(*ppad), list); in media_pipeline_cleanup()
700 list_del(&ppad->list); in media_pipeline_cleanup()
716 INIT_LIST_HEAD(&pipe->pads); in media_pipeline_populate()
717 pipe->mdev = pad->graph_obj.mdev; in media_pipeline_populate()
719 walk.mdev = pipe->mdev; in media_pipeline_populate()
720 walk.stack.top = -1; in media_pipeline_populate()
726 * Use a depth-first search algorithm: as long as the stack is not in media_pipeline_populate()
738 dev_dbg(pad->graph_obj.mdev->dev, in media_pipeline_populate()
741 list_for_each_entry(ppad, &pipe->pads, list) in media_pipeline_populate()
742 dev_dbg(pad->graph_obj.mdev->dev, "- '%s':%u\n", in media_pipeline_populate()
743 ppad->pad->entity->name, ppad->pad->index); in media_pipeline_populate()
745 WARN_ON(walk.stack.top != -1); in media_pipeline_populate()
761 struct media_device *mdev = pad->graph_obj.mdev; in __media_pipeline_start()
766 lockdep_assert_held(&mdev->graph_mutex); in __media_pipeline_start()
772 if (WARN_ON(pad->pipe && pad->pipe != pipe)) in __media_pipeline_start()
773 return -EINVAL; in __media_pipeline_start()
779 if (pipe->start_count) { in __media_pipeline_start()
780 pipe->start_count++; in __media_pipeline_start()
798 list_for_each_entry(ppad, &pipe->pads, list) { in __media_pipeline_start()
799 struct media_pad *pad = ppad->pad; in __media_pipeline_start()
800 struct media_entity *entity = pad->entity; in __media_pipeline_start()
804 dev_dbg(mdev->dev, "Validating pad '%s':%u\n", pad->entity->name, in __media_pipeline_start()
805 pad->index); in __media_pipeline_start()
811 if (pad->pipe) { in __media_pipeline_start()
812 dev_dbg(mdev->dev, "Failed to start pipeline: pad '%s':%u busy\n", in __media_pipeline_start()
813 pad->entity->name, pad->index); in __media_pipeline_start()
814 ret = -EBUSY; in __media_pipeline_start()
819 * 2. Validate all active links whose sink is the current pad. in __media_pipeline_start()
821 * the connected sink pad to avoid duplicating checks. in __media_pipeline_start()
825 if (link->sink != pad && link->source != pad) in __media_pipeline_start()
829 if (link->flags & MEDIA_LNK_FL_ENABLED) in __media_pipeline_start()
834 * current pad as its sink. in __media_pipeline_start()
836 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) in __media_pipeline_start()
839 if (link->sink != pad) in __media_pipeline_start()
842 if (!entity->ops || !entity->ops->link_validate) in __media_pipeline_start()
845 ret = entity->ops->link_validate(link); in __media_pipeline_start()
847 dev_dbg(mdev->dev, in __media_pipeline_start()
848 "Link '%s':%u -> '%s':%u failed validation: %d\n", in __media_pipeline_start()
849 link->source->entity->name, in __media_pipeline_start()
850 link->source->index, in __media_pipeline_start()
851 link->sink->entity->name, in __media_pipeline_start()
852 link->sink->index, ret); in __media_pipeline_start()
856 dev_dbg(mdev->dev, in __media_pipeline_start()
857 "Link '%s':%u -> '%s':%u is valid\n", in __media_pipeline_start()
858 link->source->entity->name, in __media_pipeline_start()
859 link->source->index, in __media_pipeline_start()
860 link->sink->entity->name, in __media_pipeline_start()
861 link->sink->index); in __media_pipeline_start()
868 if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) && in __media_pipeline_start()
870 dev_dbg(mdev->dev, in __media_pipeline_start()
872 pad->entity->name, pad->index); in __media_pipeline_start()
873 ret = -ENOLINK; in __media_pipeline_start()
878 pad->pipe = pipe; in __media_pipeline_start()
881 pipe->start_count++; in __media_pipeline_start()
891 list_for_each_entry(err_ppad, &pipe->pads, list) { in __media_pipeline_start()
895 err_ppad->pad->pipe = NULL; in __media_pipeline_start()
907 struct media_device *mdev = pad->graph_obj.mdev; in media_pipeline_start()
910 mutex_lock(&mdev->graph_mutex); in media_pipeline_start()
912 mutex_unlock(&mdev->graph_mutex); in media_pipeline_start()
919 struct media_pipeline *pipe = pad->pipe; in __media_pipeline_stop()
929 if (--pipe->start_count) in __media_pipeline_stop()
932 list_for_each_entry(ppad, &pipe->pads, list) in __media_pipeline_stop()
933 ppad->pad->pipe = NULL; in __media_pipeline_stop()
937 if (pipe->allocated) in __media_pipeline_stop()
944 struct media_device *mdev = pad->graph_obj.mdev; in media_pipeline_stop()
946 mutex_lock(&mdev->graph_mutex); in media_pipeline_stop()
948 mutex_unlock(&mdev->graph_mutex); in media_pipeline_stop()
954 struct media_device *mdev = pad->graph_obj.mdev; in media_pipeline_alloc_start()
959 mutex_lock(&mdev->graph_mutex); in media_pipeline_alloc_start()
969 ret = -ENOMEM; in media_pipeline_alloc_start()
974 pipe->allocated = true; in media_pipeline_alloc_start()
982 mutex_unlock(&mdev->graph_mutex); in media_pipeline_alloc_start()
994 iter->cursor = pipe->pads.next; in __media_pipeline_pad_iter_next()
996 if (iter->cursor == &pipe->pads) in __media_pipeline_pad_iter_next()
999 pad = list_entry(iter->cursor, struct media_pipeline_pad, list)->pad; in __media_pipeline_pad_iter_next()
1000 iter->cursor = iter->cursor->next; in __media_pipeline_pad_iter_next()
1009 return media_entity_enum_init(&iter->ent_enum, pipe->mdev); in media_pipeline_entity_iter_init()
1015 media_entity_enum_cleanup(&iter->ent_enum); in media_pipeline_entity_iter_cleanup()
1025 iter->cursor = pipe->pads.next; in __media_pipeline_entity_iter_next()
1027 while (iter->cursor != &pipe->pads) { in __media_pipeline_entity_iter_next()
1031 ppad = list_entry(iter->cursor, struct media_pipeline_pad, list); in __media_pipeline_entity_iter_next()
1032 entity = ppad->pad->entity; in __media_pipeline_entity_iter_next()
1033 iter->cursor = iter->cursor->next; in __media_pipeline_entity_iter_next()
1035 if (!media_entity_enum_test_and_set(&iter->ent_enum, entity)) in __media_pipeline_entity_iter_next()
1043 /* -----------------------------------------------------------------------------
1055 list_add_tail(&link->list, head); in media_add_link()
1067 if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == MEDIA_LNK_FL_DATA_LINK) { in __media_entity_remove_link()
1068 link->source->num_links--; in __media_entity_remove_link()
1069 link->sink->num_links--; in __media_entity_remove_link()
1071 if (link->source->entity == entity) in __media_entity_remove_link()
1072 remote = link->sink->entity; in __media_entity_remove_link()
1074 remote = link->source->entity; in __media_entity_remove_link()
1076 list_for_each_entry_safe(rlink, tmp, &remote->links, list) { in __media_entity_remove_link()
1077 if (rlink != link->reverse) in __media_entity_remove_link()
1080 if (link->source->entity == entity) in __media_entity_remove_link()
1081 remote->num_backlinks--; in __media_entity_remove_link()
1084 list_del(&rlink->list); in __media_entity_remove_link()
1085 media_gobj_destroy(&rlink->graph_obj); in __media_entity_remove_link()
1088 if (--remote->num_links == 0) in __media_entity_remove_link()
1093 list_del(&link->list); in __media_entity_remove_link()
1094 media_gobj_destroy(&link->graph_obj); in __media_entity_remove_link()
1104 return -EINVAL; in media_get_pad_index()
1106 for (i = 0; i < entity->num_pads; i++) { in media_get_pad_index()
1107 if ((entity->pads[i].flags & in media_get_pad_index()
1111 if (entity->pads[i].sig_type == sig_type) in media_get_pad_index()
1114 return -EINVAL; in media_get_pad_index()
1120 struct media_entity *sink, u16 sink_pad, u32 flags) in media_create_pad_link() argument
1126 return -EINVAL; in media_create_pad_link()
1130 if (WARN_ON(!source || !sink) || in media_create_pad_link()
1131 WARN_ON(source_pad >= source->num_pads) || in media_create_pad_link()
1132 WARN_ON(sink_pad >= sink->num_pads)) in media_create_pad_link()
1133 return -EINVAL; in media_create_pad_link()
1134 if (WARN_ON(!(source->pads[source_pad].flags & MEDIA_PAD_FL_SOURCE))) in media_create_pad_link()
1135 return -EINVAL; in media_create_pad_link()
1136 if (WARN_ON(!(sink->pads[sink_pad].flags & MEDIA_PAD_FL_SINK))) in media_create_pad_link()
1137 return -EINVAL; in media_create_pad_link()
1139 link = media_add_link(&source->links); in media_create_pad_link()
1141 return -ENOMEM; in media_create_pad_link()
1143 link->source = &source->pads[source_pad]; in media_create_pad_link()
1144 link->sink = &sink->pads[sink_pad]; in media_create_pad_link()
1145 link->flags = flags; in media_create_pad_link()
1148 media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK, in media_create_pad_link()
1149 &link->graph_obj); in media_create_pad_link()
1154 backlink = media_add_link(&sink->links); in media_create_pad_link()
1157 return -ENOMEM; in media_create_pad_link()
1160 backlink->source = &source->pads[source_pad]; in media_create_pad_link()
1161 backlink->sink = &sink->pads[sink_pad]; in media_create_pad_link()
1162 backlink->flags = flags; in media_create_pad_link()
1163 backlink->is_backlink = true; in media_create_pad_link()
1166 media_gobj_create(sink->graph_obj.mdev, MEDIA_GRAPH_LINK, in media_create_pad_link()
1167 &backlink->graph_obj); in media_create_pad_link()
1169 link->reverse = backlink; in media_create_pad_link()
1170 backlink->reverse = link; in media_create_pad_link()
1172 sink->num_backlinks++; in media_create_pad_link()
1173 sink->num_links++; in media_create_pad_link()
1174 source->num_links++; in media_create_pad_link()
1176 link->source->num_links++; in media_create_pad_link()
1177 link->sink->num_links++; in media_create_pad_link()
1188 struct media_entity *sink, in media_create_pad_links() argument
1198 if (source && sink) in media_create_pad_links()
1200 sink, sink_pad, flags); in media_create_pad_links()
1203 if (!source && !sink) { in media_create_pad_links()
1207 if (source->function != source_function) in media_create_pad_links()
1209 media_device_for_each_entity(sink, mdev) { in media_create_pad_links()
1210 if (sink->function != sink_function) in media_create_pad_links()
1213 sink, sink_pad, in media_create_pad_links()
1231 if (entity->function != function) in media_create_pad_links()
1239 sink, sink_pad, flags); in media_create_pad_links()
1252 list_for_each_entry_safe(link, tmp, &entity->links, list) in __media_entity_remove_links()
1255 entity->num_links = 0; in __media_entity_remove_links()
1256 entity->num_backlinks = 0; in __media_entity_remove_links()
1262 struct media_device *mdev = entity->graph_obj.mdev; in media_entity_remove_links()
1268 mutex_lock(&mdev->graph_mutex); in media_entity_remove_links()
1270 mutex_unlock(&mdev->graph_mutex); in media_entity_remove_links()
1279 ret = media_entity_call(link->source->entity, link_setup, in __media_entity_setup_link_notify()
1280 link->source, link->sink, flags); in __media_entity_setup_link_notify()
1281 if (ret < 0 && ret != -ENOIOCTLCMD) in __media_entity_setup_link_notify()
1284 ret = media_entity_call(link->sink->entity, link_setup, in __media_entity_setup_link_notify()
1285 link->sink, link->source, flags); in __media_entity_setup_link_notify()
1286 if (ret < 0 && ret != -ENOIOCTLCMD) { in __media_entity_setup_link_notify()
1287 media_entity_call(link->source->entity, link_setup, in __media_entity_setup_link_notify()
1288 link->source, link->sink, link->flags); in __media_entity_setup_link_notify()
1292 link->flags = flags; in __media_entity_setup_link_notify()
1293 link->reverse->flags = link->flags; in __media_entity_setup_link_notify()
1302 struct media_pad *source, *sink; in __media_entity_setup_link() local
1303 int ret = -EBUSY; in __media_entity_setup_link()
1306 return -EINVAL; in __media_entity_setup_link()
1308 /* The non-modifiable link flags must not be modified. */ in __media_entity_setup_link()
1309 if ((link->flags & ~mask) != (flags & ~mask)) in __media_entity_setup_link()
1310 return -EINVAL; in __media_entity_setup_link()
1312 if (link->flags & MEDIA_LNK_FL_IMMUTABLE) in __media_entity_setup_link()
1313 return link->flags == flags ? 0 : -EINVAL; in __media_entity_setup_link()
1315 if (link->flags == flags) in __media_entity_setup_link()
1318 source = link->source; in __media_entity_setup_link()
1319 sink = link->sink; in __media_entity_setup_link()
1321 if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) && in __media_entity_setup_link()
1322 (media_pad_is_streaming(source) || media_pad_is_streaming(sink))) in __media_entity_setup_link()
1323 return -EBUSY; in __media_entity_setup_link()
1325 mdev = source->graph_obj.mdev; in __media_entity_setup_link()
1327 if (mdev->ops && mdev->ops->link_notify) { in __media_entity_setup_link()
1328 ret = mdev->ops->link_notify(link, flags, in __media_entity_setup_link()
1336 if (mdev->ops && mdev->ops->link_notify) in __media_entity_setup_link()
1337 mdev->ops->link_notify(link, flags, in __media_entity_setup_link()
1348 mutex_lock(&link->graph_obj.mdev->graph_mutex); in media_entity_setup_link()
1350 mutex_unlock(&link->graph_obj.mdev->graph_mutex); in media_entity_setup_link()
1357 media_entity_find_link(struct media_pad *source, struct media_pad *sink) in media_entity_find_link() argument
1361 for_each_media_entity_data_link(source->entity, link) { in media_entity_find_link()
1362 if (link->source->entity == source->entity && in media_entity_find_link()
1363 link->source->index == source->index && in media_entity_find_link()
1364 link->sink->entity == sink->entity && in media_entity_find_link()
1365 link->sink->index == sink->index) in media_entity_find_link()
1377 for_each_media_entity_data_link(pad->entity, link) { in media_pad_remote_pad_first()
1378 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) in media_pad_remote_pad_first()
1381 if (link->source == pad) in media_pad_remote_pad_first()
1382 return link->sink; in media_pad_remote_pad_first()
1384 if (link->sink == pad) in media_pad_remote_pad_first()
1385 return link->source; in media_pad_remote_pad_first()
1400 list_for_each_entry(link, &entity->links, list) { in media_entity_remote_pad_unique()
1404 if (((link->flags & MEDIA_LNK_FL_LINK_TYPE) != in media_entity_remote_pad_unique()
1406 !(link->flags & MEDIA_LNK_FL_ENABLED)) in media_entity_remote_pad_unique()
1410 local_pad = link->sink; in media_entity_remote_pad_unique()
1411 remote_pad = link->source; in media_entity_remote_pad_unique()
1413 local_pad = link->source; in media_entity_remote_pad_unique()
1414 remote_pad = link->sink; in media_entity_remote_pad_unique()
1417 if (local_pad->entity == entity) { in media_entity_remote_pad_unique()
1419 return ERR_PTR(-ENOTUNIQ); in media_entity_remote_pad_unique()
1426 return ERR_PTR(-ENOLINK); in media_entity_remote_pad_unique()
1437 list_for_each_entry(link, &pad->entity->links, list) { in media_pad_remote_pad_unique()
1440 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) in media_pad_remote_pad_unique()
1443 if (link->sink == pad) in media_pad_remote_pad_unique()
1444 remote_pad = link->source; in media_pad_remote_pad_unique()
1445 else if (link->source == pad) in media_pad_remote_pad_unique()
1446 remote_pad = link->sink; in media_pad_remote_pad_unique()
1451 return ERR_PTR(-ENOTUNIQ); in media_pad_remote_pad_unique()
1457 return ERR_PTR(-ENOLINK); in media_pad_remote_pad_unique()
1471 if (!entity->ops || !entity->ops->get_fwnode_pad) { in media_entity_get_fwnode_pad()
1472 for (i = 0; i < entity->num_pads; i++) { in media_entity_get_fwnode_pad()
1473 if (entity->pads[i].flags & direction_flags) in media_entity_get_fwnode_pad()
1477 return -ENXIO; in media_entity_get_fwnode_pad()
1484 ret = entity->ops->get_fwnode_pad(entity, &endpoint); in media_entity_get_fwnode_pad()
1488 if (ret >= entity->num_pads) in media_entity_get_fwnode_pad()
1489 return -ENXIO; in media_entity_get_fwnode_pad()
1491 if (!(entity->pads[ret].flags & direction_flags)) in media_entity_get_fwnode_pad()
1492 return -ENXIO; in media_entity_get_fwnode_pad()
1503 if (pad->pipe) in media_entity_pipeline()
1504 return pad->pipe; in media_entity_pipeline()
1513 return pad->pipe; in media_pad_pipeline()
1522 intf->type = intf_type; in media_interface_init()
1523 intf->flags = flags; in media_interface_init()
1524 INIT_LIST_HEAD(&intf->links); in media_interface_init()
1526 media_gobj_create(mdev, gobj_type, &intf->graph_obj); in media_interface_init()
1541 devnode->major = major; in media_devnode_create()
1542 devnode->minor = minor; in media_devnode_create()
1544 media_interface_init(mdev, &devnode->intf, MEDIA_GRAPH_INTF_DEVNODE, in media_devnode_create()
1553 media_remove_intf_links(&devnode->intf); in media_devnode_remove()
1554 media_gobj_destroy(&devnode->intf.graph_obj); in media_devnode_remove()
1565 link = media_add_link(&intf->links); in media_create_intf_link()
1569 link->intf = intf; in media_create_intf_link()
1570 link->entity = entity; in media_create_intf_link()
1571 link->flags = flags | MEDIA_LNK_FL_INTERFACE_LINK; in media_create_intf_link()
1574 media_gobj_create(intf->graph_obj.mdev, MEDIA_GRAPH_LINK, in media_create_intf_link()
1575 &link->graph_obj); in media_create_intf_link()
1583 list_del(&link->list); in __media_remove_intf_link()
1584 media_gobj_destroy(&link->graph_obj); in __media_remove_intf_link()
1591 struct media_device *mdev = link->graph_obj.mdev; in media_remove_intf_link()
1597 mutex_lock(&mdev->graph_mutex); in media_remove_intf_link()
1599 mutex_unlock(&mdev->graph_mutex); in media_remove_intf_link()
1607 list_for_each_entry_safe(link, tmp, &intf->links, list) in __media_remove_intf_links()
1615 struct media_device *mdev = intf->graph_obj.mdev; in media_remove_intf_links()
1621 mutex_lock(&mdev->graph_mutex); in media_remove_intf_links()
1623 mutex_unlock(&mdev->graph_mutex); in media_remove_intf_links()
1632 link = media_add_link(&primary->links); in media_create_ancillary_link()
1634 return ERR_PTR(-ENOMEM); in media_create_ancillary_link()
1636 link->gobj0 = &primary->graph_obj; in media_create_ancillary_link()
1637 link->gobj1 = &ancillary->graph_obj; in media_create_ancillary_link()
1638 link->flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED | in media_create_ancillary_link()
1642 media_gobj_create(primary->graph_obj.mdev, MEDIA_GRAPH_LINK, in media_create_ancillary_link()
1643 &link->graph_obj); in media_create_ancillary_link()
1654 : list_first_entry(&entity->links, typeof(*link), list); in __media_entity_next_link()
1656 list_for_each_entry_from(link, &entity->links, list) in __media_entity_next_link()
1657 if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == link_type) in __media_entity_next_link()