kernel/ipq806x: Create kernel files for v6.6 (from v6.1)
[openwrt/openwrt.git] / target / linux / ipq806x / patches-6.6 / 002-v6.2-06-clk-qcom-krait-cc-convert-to-parent_data-API.patch
1 From 56a655e1c41a86445cf2de656649ad93424b2a63 Mon Sep 17 00:00:00 2001
2 From: Christian Marangi <ansuelsmth@gmail.com>
3 Date: Wed, 9 Nov 2022 01:56:31 +0100
4 Subject: [PATCH 6/6] clk: qcom: krait-cc: convert to parent_data API
5
6 Modernize the krait-cc driver to parent-data API and refactor to drop
7 any use of parent_names. From Documentation all the required clocks should
8 be declared in DTS so fw_name can be correctly used to get the parents
9 for all the muxes. .name is also declared to save compatibility with old
10 DT.
11
12 While at it also drop some hardcoded index and introduce an enum to make
13 index values more clear.
14
15 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
16 Signed-off-by: Bjorn Andersson <andersson@kernel.org>
17 Link: https://lore.kernel.org/r/20221109005631.3189-5-ansuelsmth@gmail.com
18 ---
19 drivers/clk/qcom/krait-cc.c | 202 ++++++++++++++++++++----------------
20 1 file changed, 112 insertions(+), 90 deletions(-)
21
22 --- a/drivers/clk/qcom/krait-cc.c
23 +++ b/drivers/clk/qcom/krait-cc.c
24 @@ -15,6 +15,16 @@
25
26 #include "clk-krait.h"
27
28 +enum {
29 + cpu0_mux = 0,
30 + cpu1_mux,
31 + cpu2_mux,
32 + cpu3_mux,
33 + l2_mux,
34 +
35 + clks_max,
36 +};
37 +
38 static unsigned int sec_mux_map[] = {
39 2,
40 0,
41 @@ -69,21 +79,23 @@ static int krait_notifier_register(struc
42 return ret;
43 }
44
45 -static int
46 +static struct clk_hw *
47 krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
48 {
49 struct krait_div2_clk *div;
50 + static struct clk_parent_data p_data[1];
51 struct clk_init_data init = {
52 - .num_parents = 1,
53 + .num_parents = ARRAY_SIZE(p_data),
54 .ops = &krait_div2_clk_ops,
55 .flags = CLK_SET_RATE_PARENT,
56 };
57 - const char *p_names[1];
58 + struct clk_hw *clk;
59 + char *parent_name;
60 int cpu, ret;
61
62 div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
63 if (!div)
64 - return -ENOMEM;
65 + return ERR_PTR(-ENOMEM);
66
67 div->width = 2;
68 div->shift = 6;
69 @@ -93,18 +105,25 @@ krait_add_div(struct device *dev, int id
70
71 init.name = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
72 if (!init.name)
73 - return -ENOMEM;
74 + return ERR_PTR(-ENOMEM);
75
76 - init.parent_names = p_names;
77 - p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
78 - if (!p_names[0]) {
79 - kfree(init.name);
80 - return -ENOMEM;
81 + init.parent_data = p_data;
82 + parent_name = kasprintf(GFP_KERNEL, "hfpll%s", s);
83 + if (!parent_name) {
84 + clk = ERR_PTR(-ENOMEM);
85 + goto err_parent_name;
86 }
87
88 + p_data[0].fw_name = parent_name;
89 + p_data[0].name = parent_name;
90 +
91 ret = devm_clk_hw_register(dev, &div->hw);
92 - if (ret)
93 - goto err;
94 + if (ret) {
95 + clk = ERR_PTR(ret);
96 + goto err_clk;
97 + }
98 +
99 + clk = &div->hw;
100
101 /* clk-krait ignore any rate change if mux is not flagged as enabled */
102 if (id < 0)
103 @@ -113,33 +132,36 @@ krait_add_div(struct device *dev, int id
104 else
105 clk_prepare_enable(div->hw.clk);
106
107 -err:
108 - kfree(p_names[0]);
109 +err_clk:
110 + kfree(parent_name);
111 +err_parent_name:
112 kfree(init.name);
113
114 - return ret;
115 + return clk;
116 }
117
118 -static int
119 +static struct clk_hw *
120 krait_add_sec_mux(struct device *dev, int id, const char *s,
121 unsigned int offset, bool unique_aux)
122 {
123 int cpu, ret;
124 struct krait_mux_clk *mux;
125 - static const char *sec_mux_list[] = {
126 - "qsb",
127 - "acpu_aux",
128 + static struct clk_parent_data sec_mux_list[2] = {
129 + { .name = "qsb", .fw_name = "qsb" },
130 + {},
131 };
132 struct clk_init_data init = {
133 - .parent_names = sec_mux_list,
134 + .parent_data = sec_mux_list,
135 .num_parents = ARRAY_SIZE(sec_mux_list),
136 .ops = &krait_mux_clk_ops,
137 .flags = CLK_SET_RATE_PARENT,
138 };
139 + struct clk_hw *clk;
140 + char *parent_name;
141
142 mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
143 if (!mux)
144 - return -ENOMEM;
145 + return ERR_PTR(-ENOMEM);
146
147 mux->offset = offset;
148 mux->lpl = id >= 0;
149 @@ -159,23 +181,33 @@ krait_add_sec_mux(struct device *dev, in
150
151 init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
152 if (!init.name)
153 - return -ENOMEM;
154 + return ERR_PTR(-ENOMEM);
155
156 if (unique_aux) {
157 - sec_mux_list[0] = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
158 - if (!sec_mux_list[0]) {
159 - ret = -ENOMEM;
160 + parent_name = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
161 + if (!parent_name) {
162 + clk = ERR_PTR(-ENOMEM);
163 goto err_aux;
164 }
165 + sec_mux_list[1].fw_name = parent_name;
166 + sec_mux_list[1].name = parent_name;
167 + } else {
168 + sec_mux_list[1].name = "apu_aux";
169 }
170
171 ret = devm_clk_hw_register(dev, &mux->hw);
172 - if (ret)
173 - goto unique_aux;
174 + if (ret) {
175 + clk = ERR_PTR(ret);
176 + goto err_clk;
177 + }
178 +
179 + clk = &mux->hw;
180
181 ret = krait_notifier_register(dev, mux->hw.clk, mux);
182 - if (ret)
183 - goto unique_aux;
184 + if (ret) {
185 + clk = ERR_PTR(ret);
186 + goto err_clk;
187 + }
188
189 /* clk-krait ignore any rate change if mux is not flagged as enabled */
190 if (id < 0)
191 @@ -184,28 +216,29 @@ krait_add_sec_mux(struct device *dev, in
192 else
193 clk_prepare_enable(mux->hw.clk);
194
195 -unique_aux:
196 +err_clk:
197 if (unique_aux)
198 - kfree(sec_mux_list[0]);
199 + kfree(parent_name);
200 err_aux:
201 kfree(init.name);
202 - return ret;
203 + return clk;
204 }
205
206 -static struct clk *
207 -krait_add_pri_mux(struct device *dev, int id, const char *s,
208 - unsigned int offset)
209 +static struct clk_hw *
210 +krait_add_pri_mux(struct device *dev, struct clk_hw *hfpll_div, struct clk_hw *sec_mux,
211 + int id, const char *s, unsigned int offset)
212 {
213 int ret;
214 struct krait_mux_clk *mux;
215 - const char *p_names[3];
216 + static struct clk_parent_data p_data[3];
217 struct clk_init_data init = {
218 - .parent_names = p_names,
219 - .num_parents = ARRAY_SIZE(p_names),
220 + .parent_data = p_data,
221 + .num_parents = ARRAY_SIZE(p_data),
222 .ops = &krait_mux_clk_ops,
223 .flags = CLK_SET_RATE_PARENT,
224 };
225 - struct clk *clk;
226 + struct clk_hw *clk;
227 + char *hfpll_name;
228
229 mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
230 if (!mux)
231 @@ -223,55 +256,44 @@ krait_add_pri_mux(struct device *dev, in
232 if (!init.name)
233 return ERR_PTR(-ENOMEM);
234
235 - p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
236 - if (!p_names[0]) {
237 + hfpll_name = kasprintf(GFP_KERNEL, "hfpll%s", s);
238 + if (!hfpll_name) {
239 clk = ERR_PTR(-ENOMEM);
240 - goto err_p0;
241 + goto err_hfpll;
242 }
243
244 - p_names[1] = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
245 - if (!p_names[1]) {
246 - clk = ERR_PTR(-ENOMEM);
247 - goto err_p1;
248 - }
249 + p_data[0].fw_name = hfpll_name;
250 + p_data[0].name = hfpll_name;
251
252 - p_names[2] = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
253 - if (!p_names[2]) {
254 - clk = ERR_PTR(-ENOMEM);
255 - goto err_p2;
256 - }
257 + p_data[1].hw = hfpll_div;
258 + p_data[2].hw = sec_mux;
259
260 ret = devm_clk_hw_register(dev, &mux->hw);
261 if (ret) {
262 clk = ERR_PTR(ret);
263 - goto err_p3;
264 + goto err_clk;
265 }
266
267 - clk = mux->hw.clk;
268 + clk = &mux->hw;
269
270 - ret = krait_notifier_register(dev, clk, mux);
271 + ret = krait_notifier_register(dev, mux->hw.clk, mux);
272 if (ret)
273 clk = ERR_PTR(ret);
274
275 -err_p3:
276 - kfree(p_names[2]);
277 -err_p2:
278 - kfree(p_names[1]);
279 -err_p1:
280 - kfree(p_names[0]);
281 -err_p0:
282 +err_clk:
283 + kfree(hfpll_name);
284 +err_hfpll:
285 kfree(init.name);
286 return clk;
287 }
288
289 /* id < 0 for L2, otherwise id == physical CPU number */
290 -static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux)
291 +static struct clk_hw *krait_add_clks(struct device *dev, int id, bool unique_aux)
292 {
293 - int ret;
294 + struct clk_hw *hfpll_div, *sec_mux, *pri_mux;
295 unsigned int offset;
296 void *p = NULL;
297 const char *s;
298 - struct clk *clk;
299
300 if (id >= 0) {
301 offset = 0x4501 + (0x1000 * id);
302 @@ -283,22 +305,23 @@ static struct clk *krait_add_clks(struct
303 s = "_l2";
304 }
305
306 - ret = krait_add_div(dev, id, s, offset);
307 - if (ret) {
308 - clk = ERR_PTR(ret);
309 + hfpll_div = krait_add_div(dev, id, s, offset);
310 + if (IS_ERR(hfpll_div)) {
311 + pri_mux = hfpll_div;
312 goto err;
313 }
314
315 - ret = krait_add_sec_mux(dev, id, s, offset, unique_aux);
316 - if (ret) {
317 - clk = ERR_PTR(ret);
318 + sec_mux = krait_add_sec_mux(dev, id, s, offset, unique_aux);
319 + if (IS_ERR(sec_mux)) {
320 + pri_mux = sec_mux;
321 goto err;
322 }
323
324 - clk = krait_add_pri_mux(dev, id, s, offset);
325 + pri_mux = krait_add_pri_mux(dev, hfpll_div, sec_mux, id, s, offset);
326 +
327 err:
328 kfree(p);
329 - return clk;
330 + return pri_mux;
331 }
332
333 static struct clk *krait_of_get(struct of_phandle_args *clkspec, void *data)
334 @@ -306,7 +329,7 @@ static struct clk *krait_of_get(struct o
335 unsigned int idx = clkspec->args[0];
336 struct clk **clks = data;
337
338 - if (idx >= 5) {
339 + if (idx >= clks_max) {
340 pr_err("%s: invalid clock index %d\n", __func__, idx);
341 return ERR_PTR(-EINVAL);
342 }
343 @@ -327,9 +350,8 @@ static int krait_cc_probe(struct platfor
344 const struct of_device_id *id;
345 unsigned long cur_rate, aux_rate;
346 int cpu;
347 - struct clk *clk;
348 - struct clk **clks;
349 - struct clk *l2_pri_mux_clk;
350 + struct clk_hw *mux, *l2_pri_mux;
351 + struct clk *clk, **clks;
352
353 id = of_match_device(krait_cc_match_table, dev);
354 if (!id)
355 @@ -348,21 +370,21 @@ static int krait_cc_probe(struct platfor
356 }
357
358 /* Krait configurations have at most 4 CPUs and one L2 */
359 - clks = devm_kcalloc(dev, 5, sizeof(*clks), GFP_KERNEL);
360 + clks = devm_kcalloc(dev, clks_max, sizeof(*clks), GFP_KERNEL);
361 if (!clks)
362 return -ENOMEM;
363
364 for_each_possible_cpu(cpu) {
365 - clk = krait_add_clks(dev, cpu, id->data);
366 + mux = krait_add_clks(dev, cpu, id->data);
367 if (IS_ERR(clk))
368 return PTR_ERR(clk);
369 - clks[cpu] = clk;
370 + clks[cpu] = mux->clk;
371 }
372
373 - l2_pri_mux_clk = krait_add_clks(dev, -1, id->data);
374 - if (IS_ERR(l2_pri_mux_clk))
375 - return PTR_ERR(l2_pri_mux_clk);
376 - clks[4] = l2_pri_mux_clk;
377 + l2_pri_mux = krait_add_clks(dev, -1, id->data);
378 + if (IS_ERR(l2_pri_mux))
379 + return PTR_ERR(l2_pri_mux);
380 + clks[l2_mux] = l2_pri_mux->clk;
381
382 /*
383 * We don't want the CPU or L2 clocks to be turned off at late init
384 @@ -372,7 +394,7 @@ static int krait_cc_probe(struct platfor
385 * they take over.
386 */
387 for_each_online_cpu(cpu) {
388 - clk_prepare_enable(l2_pri_mux_clk);
389 + clk_prepare_enable(clks[l2_mux]);
390 WARN(clk_prepare_enable(clks[cpu]),
391 "Unable to turn on CPU%d clock", cpu);
392 }
393 @@ -388,16 +410,16 @@ static int krait_cc_probe(struct platfor
394 * two different rates to force a HFPLL reinit under all
395 * circumstances.
396 */
397 - cur_rate = clk_get_rate(l2_pri_mux_clk);
398 + cur_rate = clk_get_rate(clks[l2_mux]);
399 aux_rate = 384000000;
400 if (cur_rate < aux_rate) {
401 pr_info("L2 @ Undefined rate. Forcing new rate.\n");
402 cur_rate = aux_rate;
403 }
404 - clk_set_rate(l2_pri_mux_clk, aux_rate);
405 - clk_set_rate(l2_pri_mux_clk, 2);
406 - clk_set_rate(l2_pri_mux_clk, cur_rate);
407 - pr_info("L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000);
408 + clk_set_rate(clks[l2_mux], aux_rate);
409 + clk_set_rate(clks[l2_mux], 2);
410 + clk_set_rate(clks[l2_mux], cur_rate);
411 + pr_info("L2 @ %lu KHz\n", clk_get_rate(clks[l2_mux]) / 1000);
412 for_each_possible_cpu(cpu) {
413 clk = clks[cpu];
414 cur_rate = clk_get_rate(clk);