/* Return a pointer to the ISP video instance at the far end of the pipeline. */ static int isp_video_get_graph_data(struct isp_video *video, struct isp_pipeline *pipe) { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; struct media_device *mdev = entity->graph_obj.mdev; struct isp_video *far_end = NULL; int ret; mutex_lock(&mdev->graph_mutex); ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev); if (ret) { mutex_unlock(&mdev->graph_mutex); return ret; } media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { struct isp_video *__video; media_entity_enum_set(&pipe->ent_enum, entity); if (far_end != NULL) continue; if (entity == &video->video.entity) continue; if (!is_media_entity_v4l2_video_device(entity)) continue; __video = to_isp_video(media_entity_to_video_device(entity)); if (__video->type != video->type) far_end = __video; } mutex_unlock(&mdev->graph_mutex); media_entity_graph_walk_cleanup(&graph); if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { pipe->input = far_end; pipe->output = video; } else { if (far_end == NULL) return -EPIPE; pipe->input = video; pipe->output = far_end; } return 0; }
/* * iss_pipeline_link_notify - Link management notification callback * @link: The link * @flags: New link flags that will be applied * * React to link management on powered pipelines by updating the use count of * all entities in the source and sink sides of the link. Entities are powered * on or off accordingly. * * Return 0 on success or a negative error code on failure. Powering entities * off is assumed to never fail. This function will not fail for disconnection * events. */ static int iss_pipeline_link_notify(struct media_link *link, u32 flags, unsigned int notification) { struct media_entity_graph *graph = &container_of(link->graph_obj.mdev, struct iss_device, media_dev)->pm_count_graph; struct media_entity *source = link->source->entity; struct media_entity *sink = link->sink->entity; int source_use; int sink_use; int ret; if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) { ret = media_entity_graph_walk_init(graph, link->graph_obj.mdev); if (ret) return ret; } source_use = iss_pipeline_pm_use_count(source, graph); sink_use = iss_pipeline_pm_use_count(sink, graph); if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && !(flags & MEDIA_LNK_FL_ENABLED)) { /* Powering off entities is assumed to never fail. */ iss_pipeline_pm_power(source, -sink_use, graph); iss_pipeline_pm_power(sink, -source_use, graph); return 0; } if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH && (flags & MEDIA_LNK_FL_ENABLED)) { ret = iss_pipeline_pm_power(source, sink_use, graph); if (ret < 0) return ret; ret = iss_pipeline_pm_power(sink, source_use, graph); if (ret < 0) iss_pipeline_pm_power(source, -sink_use, graph); } if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH) media_entity_graph_walk_cleanup(graph); return ret; }