Commit 4bc1ab41 authored by Steve Longerbeam's avatar Steve Longerbeam Committed by Mauro Carvalho Chehab

media: imx: csi: Stop upstream before disabling IDMA channel

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: default avatarSteve Longerbeam <slongerbeam@gmail.com>
Cc: stable@vger.kernel.org	# for 4.13 and up
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 2e0fe66e
...@@ -753,10 +753,16 @@ static int csi_start(struct csi_priv *priv) ...@@ -753,10 +753,16 @@ static int csi_start(struct csi_priv *priv)
output_fi = &priv->frame_interval[priv->active_output_pad]; 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) { if (priv->dest == IPU_CSI_DEST_IDMAC) {
ret = csi_idmac_start(priv); ret = csi_idmac_start(priv);
if (ret) if (ret)
return ret; goto stop_upstream;
} }
ret = csi_setup(priv); ret = csi_setup(priv);
...@@ -784,6 +790,8 @@ static int csi_start(struct csi_priv *priv) ...@@ -784,6 +790,8 @@ static int csi_start(struct csi_priv *priv)
idmac_stop: idmac_stop:
if (priv->dest == IPU_CSI_DEST_IDMAC) if (priv->dest == IPU_CSI_DEST_IDMAC)
csi_idmac_stop(priv); csi_idmac_stop(priv);
stop_upstream:
v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
return ret; return ret;
} }
...@@ -799,6 +807,9 @@ static void csi_stop(struct csi_priv *priv) ...@@ -799,6 +807,9 @@ static void csi_stop(struct csi_priv *priv)
*/ */
ipu_csi_disable(priv->csi); ipu_csi_disable(priv->csi);
/* stop upstream */
v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
if (priv->dest == IPU_CSI_DEST_IDMAC) { if (priv->dest == IPU_CSI_DEST_IDMAC) {
csi_idmac_stop(priv); csi_idmac_stop(priv);
...@@ -966,23 +977,13 @@ static int csi_s_stream(struct v4l2_subdev *sd, int enable) ...@@ -966,23 +977,13 @@ static int csi_s_stream(struct v4l2_subdev *sd, int enable)
goto update_count; goto update_count;
if (enable) { 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"); dev_dbg(priv->dev, "stream ON\n");
ret = csi_start(priv); ret = csi_start(priv);
if (ret) { if (ret)
v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
goto out; goto out;
}
} else { } else {
dev_dbg(priv->dev, "stream OFF\n"); dev_dbg(priv->dev, "stream OFF\n");
/* CSI must be stopped first, then stop upstream */
csi_stop(priv); csi_stop(priv);
v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
} }
update_count: update_count:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment