@@ -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
*/
@@ -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;
@@ -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
*
@@ -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