]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
v4l: dma: Use media graph traversal to stream on/off subdevs
authorSatish Kumar Nagireddy <satish.nagireddy.nagireddy@xilinx.com>
Thu, 27 Sep 2018 05:32:41 +0000 (22:32 -0700)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 27 Sep 2018 07:28:14 +0000 (09:28 +0200)
This patch uses media framework specific implementation to parse
all the subdevs in the graph in order to stream on/off.

Depth first search algorithm is employed to traverse the nodes
and leaf node of the graph will stream on/off first and so on.

Case 1:
cam -> mipi -> scaler -> dma
The order of stream on is cam, mipi and scaler.
The order of stream off is cam, mipi and scaler.

Case 2:
cam  |      | dma
       mipi
cam2 |      | dma2
The order of stream on is cam, mipi and cam2.

Case 3 (mem2mem):
dma -> scaler -> colconv -> dma2
The order of stream on is colconv, scaler. In mem2mem graph will
traverse same subdevs twice but won't stream-on if it is already
streaming.

Signed-off-by: Satish Kumar Nagireddy <satish.nagireddy.nagireddy@xilinx.com>
Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/media/platform/xilinx/xilinx-dma.c

index d198111b50757627cc473e5d2feb40ee335f9c4c..6282cbe39c1b58b8c224481d3ab7f0b832f8d7f2 100644 (file)
@@ -139,41 +139,32 @@ static struct media_pad *xvip_get_entity_sink(struct media_entity *entity,
 static int xvip_pipeline_start_stop(struct xvip_composite_device *xdev,
                                    struct xvip_dma *dma, bool start)
 {
-       struct media_entity *entity;
-       struct media_pad *pad;
+       struct media_graph graph;
+       struct media_entity *entity = &dma->video.entity;
+       struct media_device *mdev = entity->graph_obj.mdev;
        struct v4l2_subdev *subdev;
        bool is_streaming;
        int ret;
 
-       entity = &dma->video.entity;
-       pad = NULL;
+       mutex_lock(&mdev->graph_mutex);
 
-       while (1) {
-               pad = xvip_get_entity_sink(entity, pad);
-               if (!pad)
-                       break;
+       /* Walk the graph to locate the subdev nodes */
+       ret = media_graph_walk_init(&graph, mdev);
+       if (ret) {
+               mutex_unlock(&mdev->graph_mutex);
+               return ret;
+       }
 
-               /*
-                * This will walk through the subdevices multiple times in case
-                * of mem2mem pipeline. But there won't be any issues as
-                * driver is maintaining list of streamed subdevices
-                */
-               if (xdev->v4l2_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE ||
-                   xdev->v4l2_caps & V4L2_CAP_VIDEO_CAPTURE) {
-                       if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                               break;
-               } else {
-                       if (!(pad->flags & MEDIA_PAD_FL_SOURCE))
-                               break;
-               }
+       media_graph_walk_start(&graph, entity);
 
-               pad = media_entity_remote_pad(pad);
-               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                       break;
+       while ((entity = media_graph_walk_next(&graph))) {
+               /* We want to stream on/off only subdevs */
+               if (!is_media_entity_v4l2_subdev(entity))
+                       continue;
 
-               entity = pad->entity;
                subdev = media_entity_to_v4l2_subdev(entity);
 
+               /* This is to maintain list of stream on/off devices */
                is_streaming = xvip_subdev_set_streaming(xdev, subdev, start);
 
                /*
@@ -191,6 +182,9 @@ static int xvip_pipeline_start_stop(struct xvip_composite_device *xdev,
                }
        }
 
+       mutex_unlock(&mdev->graph_mutex);
+       media_graph_walk_cleanup(&graph);
+
        return 0;
 }