Commit d9f44345 authored by Tomi Valkeinen's avatar Tomi Valkeinen Committed by Mauro Carvalho Chehab
Browse files

media: mc: entity: add alloc variant of pipeline_start



Add new variant of media_pipeline_start(), media_pipeline_alloc_start().

media_pipeline_alloc_start() can be used by drivers that do not need to
extend the media_pipeline. The function will either use the pipeline
already associated with the entity, if such exists, or allocate a new
pipeline.

When media_pipeline_stop() is called and the pipeline's use count drops
to zero, the pipeline is automatically freed.

Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 98d79dc3
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -530,6 +530,8 @@ void __media_pipeline_stop(struct media_entity *entity)

	media_graph_walk_cleanup(graph);

	if (pipe->allocated)
		kfree(pipe);
}
EXPORT_SYMBOL_GPL(__media_pipeline_stop);

@@ -543,6 +545,42 @@ void media_pipeline_stop(struct media_entity *entity)
}
EXPORT_SYMBOL_GPL(media_pipeline_stop);

__must_check int media_pipeline_alloc_start(struct media_entity *entity)
{
	struct media_device *mdev = entity->graph_obj.mdev;
	struct media_pipeline *new_pipe = NULL;
	struct media_pipeline *pipe;
	int ret;

	mutex_lock(&mdev->graph_mutex);

	/*
	 * Is the entity already part of a pipeline? If not, we need to allocate
	 * a pipe.
	 */
	pipe = media_entity_pipeline(entity);
	if (!pipe) {
		new_pipe = kzalloc(sizeof(*new_pipe), GFP_KERNEL);
		if (!new_pipe) {
			ret = -ENOMEM;
			goto out;
		}

		pipe = new_pipe;
		pipe->allocated = true;
	}

	ret = __media_pipeline_start(entity, pipe);
	if (ret)
		kfree(new_pipe);

out:
	mutex_unlock(&mdev->graph_mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(media_pipeline_alloc_start);

/* -----------------------------------------------------------------------------
 * Links management
 */
+11 −0
Original line number Diff line number Diff line
@@ -1143,6 +1143,17 @@ void __video_device_pipeline_stop(struct video_device *vdev)
}
EXPORT_SYMBOL_GPL(__video_device_pipeline_stop);

__must_check int video_device_pipeline_alloc_start(struct video_device *vdev)
{
	struct media_entity *entity = &vdev->entity;

	if (entity->num_pads != 1)
		return -ENODEV;

	return media_pipeline_alloc_start(entity);
}
EXPORT_SYMBOL_GPL(video_device_pipeline_alloc_start);

struct media_pipeline *video_device_pipeline(struct video_device *vdev)
{
	struct media_entity *entity = &vdev->entity;
+15 −0
Original line number Diff line number Diff line
@@ -100,10 +100,12 @@ struct media_graph {
/**
 * struct media_pipeline - Media pipeline related information
 *
 * @allocated:		Media pipeline allocated and freed by the framework
 * @start_count:	Media pipeline start - stop count
 * @graph:		Media graph walk during pipeline start / stop
 */
struct media_pipeline {
	bool allocated;
	int start_count;
	struct media_graph graph;
};
@@ -1092,6 +1094,19 @@ void media_pipeline_stop(struct media_entity *entity);
 */
void __media_pipeline_stop(struct media_entity *entity);

/**
 * media_pipeline_alloc_start - Mark a pipeline as streaming
 * @entity: Starting entity
 *
 * media_pipeline_alloc_start() is similar to media_pipeline_start() but instead
 * of working on a given pipeline the function will use an existing pipeline if
 * the entity is already part of a pipeline, or allocate a new pipeline.
 *
 * Calls to media_pipeline_alloc_start() must be matched with
 * media_pipeline_stop().
 */
__must_check int media_pipeline_alloc_start(struct media_entity *entity);

/**
 * media_devnode_create() - creates and initializes a device node interface
 *
+14 −0
Original line number Diff line number Diff line
@@ -607,6 +607,20 @@ void video_device_pipeline_stop(struct video_device *vdev);
 */
void __video_device_pipeline_stop(struct video_device *vdev);

/**
 * video_device_pipeline_alloc_start - Mark a pipeline as streaming
 * @vdev: Starting video device
 *
 * video_device_pipeline_alloc_start() is similar to video_device_pipeline_start()
 * but instead of working on a given pipeline the function will use an
 * existing pipeline if the video device is already part of a pipeline, or
 * allocate a new pipeline.
 *
 * Calls to video_device_pipeline_alloc_start() must be matched with
 * video_device_pipeline_stop().
 */
__must_check int video_device_pipeline_alloc_start(struct video_device *vdev);

/**
 * video_device_pipeline - Get the media pipeline a video device is part of
 * @vdev: The video device