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
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
12 While at it also drop some hardcoded index and introduce an enum to make
13 index values more clear.
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
19 drivers/clk/qcom/krait-cc.c | 202 ++++++++++++++++++++----------------
20 1 file changed, 112 insertions(+), 90 deletions(-)
22 --- a/drivers/clk/qcom/krait-cc.c
23 +++ b/drivers/clk/qcom/krait-cc.c
26 #include "clk-krait.h"
38 static unsigned int sec_mux_map[] = {
41 @@ -69,21 +79,23 @@ static int krait_notifier_register(struc
46 +static struct clk_hw *
47 krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
49 struct krait_div2_clk *div;
50 + static struct clk_parent_data p_data[1];
51 struct clk_init_data init = {
53 + .num_parents = ARRAY_SIZE(p_data),
54 .ops = &krait_div2_clk_ops,
55 .flags = CLK_SET_RATE_PARENT,
57 - const char *p_names[1];
62 div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
65 + return ERR_PTR(-ENOMEM);
69 @@ -93,18 +105,25 @@ krait_add_div(struct device *dev, int id
71 init.name = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
74 + return ERR_PTR(-ENOMEM);
76 - init.parent_names = p_names;
77 - p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
81 + init.parent_data = p_data;
82 + parent_name = kasprintf(GFP_KERNEL, "hfpll%s", s);
84 + clk = ERR_PTR(-ENOMEM);
85 + goto err_parent_name;
88 + p_data[0].fw_name = parent_name;
89 + p_data[0].name = parent_name;
91 ret = devm_clk_hw_register(dev, &div->hw);
101 /* clk-krait ignore any rate change if mux is not flagged as enabled */
103 @@ -113,33 +132,36 @@ krait_add_div(struct device *dev, int id
105 clk_prepare_enable(div->hw.clk);
110 + kfree(parent_name);
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)
124 struct krait_mux_clk *mux;
125 - static const char *sec_mux_list[] = {
128 + static struct clk_parent_data sec_mux_list[2] = {
129 + { .name = "qsb", .fw_name = "qsb" },
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,
139 + struct clk_hw *clk;
142 mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
145 + return ERR_PTR(-ENOMEM);
147 mux->offset = offset;
149 @@ -159,23 +181,33 @@ krait_add_sec_mux(struct device *dev, in
151 init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
154 + return ERR_PTR(-ENOMEM);
157 - sec_mux_list[0] = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
158 - if (!sec_mux_list[0]) {
160 + parent_name = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
161 + if (!parent_name) {
162 + clk = ERR_PTR(-ENOMEM);
165 + sec_mux_list[1].fw_name = parent_name;
166 + sec_mux_list[1].name = parent_name;
168 + sec_mux_list[1].name = "apu_aux";
171 ret = devm_clk_hw_register(dev, &mux->hw);
175 + clk = ERR_PTR(ret);
181 ret = krait_notifier_register(dev, mux->hw.clk, mux);
185 + clk = ERR_PTR(ret);
189 /* clk-krait ignore any rate change if mux is not flagged as enabled */
191 @@ -184,28 +216,29 @@ krait_add_sec_mux(struct device *dev, in
193 clk_prepare_enable(mux->hw.clk);
198 - kfree(sec_mux_list[0]);
199 + kfree(parent_name);
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)
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,
226 + struct clk_hw *clk;
229 mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
231 @@ -223,55 +256,44 @@ krait_add_pri_mux(struct device *dev, in
233 return ERR_PTR(-ENOMEM);
235 - p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
237 + hfpll_name = kasprintf(GFP_KERNEL, "hfpll%s", s);
239 clk = ERR_PTR(-ENOMEM);
244 - p_names[1] = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
246 - clk = ERR_PTR(-ENOMEM);
249 + p_data[0].fw_name = hfpll_name;
250 + p_data[0].name = hfpll_name;
252 - p_names[2] = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
254 - clk = ERR_PTR(-ENOMEM);
257 + p_data[1].hw = hfpll_div;
258 + p_data[2].hw = sec_mux;
260 ret = devm_clk_hw_register(dev, &mux->hw);
270 - ret = krait_notifier_register(dev, clk, mux);
271 + ret = krait_notifier_register(dev, mux->hw.clk, mux);
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)
294 + struct clk_hw *hfpll_div, *sec_mux, *pri_mux;
301 offset = 0x4501 + (0x1000 * id);
302 @@ -283,22 +305,23 @@ static struct clk *krait_add_clks(struct
306 - ret = krait_add_div(dev, id, s, offset);
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;
315 - ret = krait_add_sec_mux(dev, id, s, offset, unique_aux);
317 - clk = ERR_PTR(ret);
318 + sec_mux = krait_add_sec_mux(dev, id, s, offset, unique_aux);
319 + if (IS_ERR(sec_mux)) {
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);
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;
339 + if (idx >= clks_max) {
340 pr_err("%s: invalid clock index %d\n", __func__, idx);
341 return ERR_PTR(-EINVAL);
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;
349 - struct clk *l2_pri_mux_clk;
350 + struct clk_hw *mux, *l2_pri_mux;
351 + struct clk *clk, **clks;
353 id = of_match_device(krait_cc_match_table, dev);
355 @@ -348,21 +370,21 @@ static int krait_cc_probe(struct platfor
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);
364 for_each_possible_cpu(cpu) {
365 - clk = krait_add_clks(dev, cpu, id->data);
366 + mux = krait_add_clks(dev, cpu, id->data);
370 + clks[cpu] = mux->clk;
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;
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
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);
393 @@ -388,16 +410,16 @@ static int krait_cc_probe(struct platfor
394 * two different rates to force a HFPLL reinit under all
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");
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) {
414 cur_rate = clk_get_rate(clk);