예제 #1
0
파일: ispvideo.c 프로젝트: AK101111/linux
/* 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;
}
예제 #2
0
파일: iss.c 프로젝트: a2hojsjsjs/linux
/*
 * 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;
}