]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: imx: imx7-media-csi: Fix buffer return upon stream start failure
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Tue, 11 May 2021 23:44:40 +0000 (01:44 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 18 Sep 2021 11:42:07 +0000 (13:42 +0200)
[ Upstream commit 0ada1697ed4256b38225319c9896661142a3572d ]

When the stream fails to start, the first two buffers in the queue have
been moved to the active_vb2_buf array and are returned to vb2 by
imx7_csi_dma_unsetup_vb2_buf(). The function is called with the buffer
state set to VB2_BUF_STATE_ERROR unconditionally, which is correct when
stopping the stream, but not when the start operation fails. In that
case, the state should be set to VB2_BUF_STATE_QUEUED. Fix it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Martin Kepplinger <martin.kepplinger@puri.sm>
Reviewed-by: Rui Miguel Silva <rmfrfs@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/staging/media/imx/imx7-media-csi.c

index f85a2f5f1413bfbb796e815e8b4d69a0449c47ce..ad1bca3fe04717bcfa518a3b09998e071ebf34c1 100644 (file)
@@ -361,6 +361,7 @@ static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi,
 
                        vb->timestamp = ktime_get_ns();
                        vb2_buffer_done(vb, return_status);
+                       csi->active_vb2_buf[i] = NULL;
                }
        }
 }
@@ -386,9 +387,10 @@ static int imx7_csi_dma_setup(struct imx7_csi *csi)
        return 0;
 }
 
-static void imx7_csi_dma_cleanup(struct imx7_csi *csi)
+static void imx7_csi_dma_cleanup(struct imx7_csi *csi,
+                                enum vb2_buffer_state return_status)
 {
-       imx7_csi_dma_unsetup_vb2_buf(csi, VB2_BUF_STATE_ERROR);
+       imx7_csi_dma_unsetup_vb2_buf(csi, return_status);
        imx_media_free_dma_buf(csi->dev, &csi->underrun_buf);
 }
 
@@ -537,9 +539,10 @@ static int imx7_csi_init(struct imx7_csi *csi)
        return 0;
 }
 
-static void imx7_csi_deinit(struct imx7_csi *csi)
+static void imx7_csi_deinit(struct imx7_csi *csi,
+                           enum vb2_buffer_state return_status)
 {
-       imx7_csi_dma_cleanup(csi);
+       imx7_csi_dma_cleanup(csi, return_status);
        imx7_csi_init_default(csi);
        imx7_csi_dmareq_rff_disable(csi);
        clk_disable_unprepare(csi->mclk);
@@ -702,7 +705,7 @@ static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable)
 
                ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1);
                if (ret < 0) {
-                       imx7_csi_deinit(csi);
+                       imx7_csi_deinit(csi, VB2_BUF_STATE_QUEUED);
                        goto out_unlock;
                }
 
@@ -712,7 +715,7 @@ static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable)
 
                v4l2_subdev_call(csi->src_sd, video, s_stream, 0);
 
-               imx7_csi_deinit(csi);
+               imx7_csi_deinit(csi, VB2_BUF_STATE_ERROR);
        }
 
        csi->is_streaming = !!enable;