]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.31/media-imx-csi-stop-upstream-before-disabling-idma-channel.patch
Linux 4.19.31
[thirdparty/kernel/stable-queue.git] / releases / 4.19.31 / media-imx-csi-stop-upstream-before-disabling-idma-channel.patch
CommitLineData
7ffa1129
GKH
1From 4bc1ab41eee9d02ad2483bf8f51a7b72e3504eba Mon Sep 17 00:00:00 2001
2From: Steve Longerbeam <slongerbeam@gmail.com>
3Date: Mon, 21 Jan 2019 21:35:51 -0200
4Subject: media: imx: csi: Stop upstream before disabling IDMA channel
5
6From: Steve Longerbeam <slongerbeam@gmail.com>
7
8commit 4bc1ab41eee9d02ad2483bf8f51a7b72e3504eba upstream.
9
10Move upstream stream off to just after receiving the last EOF completion
11and disabling the CSI (and thus before disabling the IDMA channel) in
12csi_stop(). For symmetry also move upstream stream on to beginning of
13csi_start().
14
15Doing this makes csi_s_stream() more symmetric with prp_s_stream() which
16will require the same change to fix a hard lockup.
17
18Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
19Cc: stable@vger.kernel.org # for 4.13 and up
20Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
21Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
22Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
23
24---
25 drivers/staging/media/imx/imx-media-csi.c | 25 +++++++++++++------------
26 1 file changed, 13 insertions(+), 12 deletions(-)
27
28--- a/drivers/staging/media/imx/imx-media-csi.c
29+++ b/drivers/staging/media/imx/imx-media-csi.c
30@@ -722,10 +722,16 @@ static int csi_start(struct csi_priv *pr
31
32 output_fi = &priv->frame_interval[priv->active_output_pad];
33
34+ /* start upstream */
35+ ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1);
36+ ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
37+ if (ret)
38+ return ret;
39+
40 if (priv->dest == IPU_CSI_DEST_IDMAC) {
41 ret = csi_idmac_start(priv);
42 if (ret)
43- return ret;
44+ goto stop_upstream;
45 }
46
47 ret = csi_setup(priv);
48@@ -753,6 +759,8 @@ fim_off:
49 idmac_stop:
50 if (priv->dest == IPU_CSI_DEST_IDMAC)
51 csi_idmac_stop(priv);
52+stop_upstream:
53+ v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
54 return ret;
55 }
56
57@@ -768,6 +776,9 @@ static void csi_stop(struct csi_priv *pr
58 */
59 ipu_csi_disable(priv->csi);
60
61+ /* stop upstream */
62+ v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
63+
64 if (priv->dest == IPU_CSI_DEST_IDMAC) {
65 csi_idmac_stop(priv);
66
67@@ -935,23 +946,13 @@ static int csi_s_stream(struct v4l2_subd
68 goto update_count;
69
70 if (enable) {
71- /* upstream must be started first, before starting CSI */
72- ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1);
73- ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
74- if (ret)
75- goto out;
76-
77 dev_dbg(priv->dev, "stream ON\n");
78 ret = csi_start(priv);
79- if (ret) {
80- v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
81+ if (ret)
82 goto out;
83- }
84 } else {
85 dev_dbg(priv->dev, "stream OFF\n");
86- /* CSI must be stopped first, then stop upstream */
87 csi_stop(priv);
88- v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
89 }
90
91 update_count: