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: Steve Longerbeam <slongerbeam@gmail.com> Cc: stable@vger.kernel.org # for 4.13 and up Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
2e0fe66e0a
commit
4bc1ab41ee
@ -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 @@ fim_off:
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user