at91: add kernel support for sama7g5 soc
[openwrt/openwrt.git] / target / linux / at91 / patches-5.10 / 155-media-atmel-properly-get-pm_runtime.patch
1 From c7660cc977621c4a14d870d523918df067f0db39 Mon Sep 17 00:00:00 2001
2 From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
3 Date: Fri, 23 Apr 2021 16:47:42 +0200
4 Subject: [PATCH 155/247] media: atmel: properly get pm_runtime
5
6 There are several issues in the way the atmel driver handles
7 pm_runtime_get_sync():
8
9 - it doesn't check return codes;
10 - it doesn't properly decrement the usage_count on all places;
11 - it starts streaming even if pm_runtime_get_sync() fails.
12 - while it tries to get pm_runtime at the clock enable logic,
13 it doesn't check if the operation was suceeded.
14
15 Replace all occurrences of it to use the new kAPI:
16 pm_runtime_resume_and_get(), which ensures that, if the
17 return code is not negative, the usage_count was incremented.
18
19 With that, add additional checks when this is called, in order
20 to ensure that errors will be properly addressed.
21
22 Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
23 ---
24 drivers/media/platform/atmel/atmel-isc-base.c | 30 ++++++++++++++-----
25 drivers/media/platform/atmel/atmel-isi.c | 19 +++++++++---
26 2 files changed, 38 insertions(+), 11 deletions(-)
27
28 diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
29 index fe3ec8d0eaee..ce8e1351fa53 100644
30 --- a/drivers/media/platform/atmel/atmel-isc-base.c
31 +++ b/drivers/media/platform/atmel/atmel-isc-base.c
32 @@ -294,9 +294,13 @@ static int isc_wait_clk_stable(struct clk_hw *hw)
33 static int isc_clk_prepare(struct clk_hw *hw)
34 {
35 struct isc_clk *isc_clk = to_isc_clk(hw);
36 + int ret;
37
38 - if (isc_clk->id == ISC_ISPCK)
39 - pm_runtime_get_sync(isc_clk->dev);
40 + if (isc_clk->id == ISC_ISPCK) {
41 + ret = pm_runtime_resume_and_get(isc_clk->dev);
42 + if (ret < 0)
43 + return ret;
44 + }
45
46 return isc_wait_clk_stable(hw);
47 }
48 @@ -353,9 +357,13 @@ static int isc_clk_is_enabled(struct clk_hw *hw)
49 {
50 struct isc_clk *isc_clk = to_isc_clk(hw);
51 u32 status;
52 + int ret;
53
54 - if (isc_clk->id == ISC_ISPCK)
55 - pm_runtime_get_sync(isc_clk->dev);
56 + if (isc_clk->id == ISC_ISPCK) {
57 + ret = pm_runtime_resume_and_get(isc_clk->dev);
58 + if (ret < 0)
59 + return 0;
60 + }
61
62 regmap_read(isc_clk->regmap, ISC_CLKSR, &status);
63
64 @@ -807,7 +815,12 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
65 goto err_start_stream;
66 }
67
68 - pm_runtime_get_sync(isc->dev);
69 + ret = pm_runtime_resume_and_get(isc->dev);
70 + if (ret < 0) {
71 + v4l2_err(&isc->v4l2_dev, "RPM resume failed in subdev %d\n",
72 + ret);
73 + goto err_pm_get;
74 + }
75
76 ret = isc_configure(isc);
77 if (unlikely(ret))
78 @@ -838,7 +851,7 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
79
80 err_configure:
81 pm_runtime_put_sync(isc->dev);
82 -
83 +err_pm_get:
84 v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0);
85
86 err_start_stream:
87 @@ -1809,6 +1822,7 @@ static void isc_awb_work(struct work_struct *w)
88 u32 baysel;
89 unsigned long flags;
90 u32 min, max;
91 + int ret;
92
93 /* streaming is not active anymore */
94 if (isc->stop)
95 @@ -1831,7 +1845,9 @@ static void isc_awb_work(struct work_struct *w)
96 ctrls->hist_id = hist_id;
97 baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
98
99 - pm_runtime_get_sync(isc->dev);
100 + ret = pm_runtime_resume_and_get(isc->dev);
101 + if (ret < 0)
102 + return;
103
104 /*
105 * only update if we have all the required histograms and controls
106 diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
107 index d74aa73f26be..4ac5b7c19d0c 100644
108 --- a/drivers/media/platform/atmel/atmel-isi.c
109 +++ b/drivers/media/platform/atmel/atmel-isi.c
110 @@ -423,7 +423,9 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
111 struct frame_buffer *buf, *node;
112 int ret;
113
114 - pm_runtime_get_sync(isi->dev);
115 + ret = pm_runtime_resume_and_get(isi->dev);
116 + if (ret < 0)
117 + return ret;
118
119 /* Enable stream on the sub device */
120 ret = v4l2_subdev_call(isi->entity.subdev, video, s_stream, 1);
121 @@ -783,9 +785,10 @@ static int isi_enum_frameintervals(struct file *file, void *fh,
122 return 0;
123 }
124
125 -static void isi_camera_set_bus_param(struct atmel_isi *isi)
126 +static int isi_camera_set_bus_param(struct atmel_isi *isi)
127 {
128 u32 cfg1 = 0;
129 + int ret;
130
131 /* set bus param for ISI */
132 if (isi->pdata.hsync_act_low)
133 @@ -802,12 +805,16 @@ static void isi_camera_set_bus_param(struct atmel_isi *isi)
134 cfg1 |= ISI_CFG1_THMASK_BEATS_16;
135
136 /* Enable PM and peripheral clock before operate isi registers */
137 - pm_runtime_get_sync(isi->dev);
138 + ret = pm_runtime_resume_and_get(isi->dev);
139 + if (ret < 0)
140 + return ret;
141
142 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
143 isi_writel(isi, ISI_CFG1, cfg1);
144
145 pm_runtime_put(isi->dev);
146 +
147 + return 0;
148 }
149
150 /* -----------------------------------------------------------------------*/
151 @@ -1086,7 +1093,11 @@ static int isi_graph_notify_complete(struct v4l2_async_notifier *notifier)
152 dev_err(isi->dev, "No supported mediabus format found\n");
153 return ret;
154 }
155 - isi_camera_set_bus_param(isi);
156 + ret = isi_camera_set_bus_param(isi);
157 + if (ret) {
158 + dev_err(isi->dev, "Can't wake up device\n");
159 + return ret;
160 + }
161
162 ret = isi_set_default_fmt(isi);
163 if (ret) {
164 --
165 2.32.0
166