Move upstream stream off to just after receiving the last EOF completion
and disabling the CSI (and thus before disabling the IDMA channel) in
csi_stop(). For symmetry also move upstream stream on to beginning of
csi_start().

Doing this makes csi_s_stream() more symmetric with prp_s_stream() which
will require the same change to fix a hard lockup.

Signed-off-by: Steve Longerbeam <slongerb...@gmail.com>
Cc: sta...@vger.kernel.org
---
 drivers/staging/media/imx/imx-media-csi.c | 25 ++++++++++++-----------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index 920e38885292..d851ca2497b4 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -753,10 +753,16 @@ static int csi_start(struct csi_priv *priv)
 
        output_fi = &priv->frame_interval[priv->active_output_pad];
 
+       /* start upstream */
+       ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1);
+       ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
+       if (ret)
+               return ret;
+
        if (priv->dest == IPU_CSI_DEST_IDMAC) {
                ret = csi_idmac_start(priv);
                if (ret)
-                       return ret;
+                       goto stop_upstream;
        }
 
        ret = csi_setup(priv);
@@ -784,6 +790,8 @@ static int csi_start(struct csi_priv *priv)
 idmac_stop:
        if (priv->dest == IPU_CSI_DEST_IDMAC)
                csi_idmac_stop(priv);
+stop_upstream:
+       v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
        return ret;
 }
 
@@ -799,6 +807,9 @@ static void csi_stop(struct csi_priv *priv)
         */
        ipu_csi_disable(priv->csi);
 
+       /* stop upstream */
+       v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
+
        if (priv->dest == IPU_CSI_DEST_IDMAC) {
                csi_idmac_stop(priv);
 
@@ -966,23 +977,13 @@ static int csi_s_stream(struct v4l2_subdev *sd, int 
enable)
                goto update_count;
 
        if (enable) {
-               /* upstream must be started first, before starting CSI */
-               ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1);
-               ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
-               if (ret)
-                       goto out;
-
                dev_dbg(priv->dev, "stream ON\n");
                ret = csi_start(priv);
-               if (ret) {
-                       v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
+               if (ret)
                        goto out;
-               }
        } else {
                dev_dbg(priv->dev, "stream OFF\n");
-               /* CSI must be stopped first, then stop upstream */
                csi_stop(priv);
-               v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
        }
 
 update_count:
-- 
2.17.1

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to