diff options
author | Michael Turquette <mturquette@baylibre.com> | 2016-04-30 15:47:36 -0400 |
---|---|---|
committer | Michael Turquette <mturquette@baylibre.com> | 2016-06-22 21:02:35 -0400 |
commit | 55d42c40dd8aa7384aa5c5295ef9037db2b00226 (patch) | |
tree | fb4da86435984c61973000b0b240c6743401ffa2 | |
parent | 6282a2da098b07763ac5d8a710b759f17d63d1b3 (diff) |
clk: meson8b: clean up cpu clocks
Remove the cpu clock registration function and helpers. Replace
unnecessary configuration struct with static initialization of the
desired clock type.
Ninja rename a5_clk to cpu_clk to better align with cpufreq convention.
Tested-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Michael Turquette <mturquette@baylibre.com>
-rw-r--r-- | drivers/clk/meson/clk-cpu.c | 73 | ||||
-rw-r--r-- | drivers/clk/meson/clkc.c | 4 | ||||
-rw-r--r-- | drivers/clk/meson/clkc.h | 25 | ||||
-rw-r--r-- | drivers/clk/meson/meson8b-clkc.c | 47 |
4 files changed, 59 insertions, 90 deletions
diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c index f7c30ea54ca8..f8b2b7efd016 100644 --- a/drivers/clk/meson/clk-cpu.c +++ b/drivers/clk/meson/clk-cpu.c | |||
@@ -51,13 +51,6 @@ | |||
51 | 51 | ||
52 | #include "clkc.h" | 52 | #include "clkc.h" |
53 | 53 | ||
54 | struct meson_clk_cpu { | ||
55 | struct notifier_block clk_nb; | ||
56 | const struct clk_div_table *div_table; | ||
57 | struct clk_hw hw; | ||
58 | void __iomem *base; | ||
59 | u16 reg_off; | ||
60 | }; | ||
61 | #define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw) | 54 | #define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw) |
62 | #define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb) | 55 | #define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb) |
63 | 56 | ||
@@ -119,6 +112,7 @@ static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw, | |||
119 | return parent_rate / div; | 112 | return parent_rate / div; |
120 | } | 113 | } |
121 | 114 | ||
115 | /* FIXME MUX1 & MUX2 should be struct clk_hw objects */ | ||
122 | static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu, | 116 | static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu, |
123 | struct clk_notifier_data *ndata) | 117 | struct clk_notifier_data *ndata) |
124 | { | 118 | { |
@@ -140,6 +134,7 @@ static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu, | |||
140 | return 0; | 134 | return 0; |
141 | } | 135 | } |
142 | 136 | ||
137 | /* FIXME MUX1 & MUX2 should be struct clk_hw objects */ | ||
143 | static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu, | 138 | static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu, |
144 | struct clk_notifier_data *ndata) | 139 | struct clk_notifier_data *ndata) |
145 | { | 140 | { |
@@ -161,7 +156,7 @@ static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu, | |||
161 | * PLL clock is to be changed. We use the xtal input as temporary parent | 156 | * PLL clock is to be changed. We use the xtal input as temporary parent |
162 | * while the PLL frequency is stabilized. | 157 | * while the PLL frequency is stabilized. |
163 | */ | 158 | */ |
164 | static int meson_clk_cpu_notifier_cb(struct notifier_block *nb, | 159 | int meson_clk_cpu_notifier_cb(struct notifier_block *nb, |
165 | unsigned long event, void *data) | 160 | unsigned long event, void *data) |
166 | { | 161 | { |
167 | struct clk_notifier_data *ndata = data; | 162 | struct clk_notifier_data *ndata = data; |
@@ -176,68 +171,8 @@ static int meson_clk_cpu_notifier_cb(struct notifier_block *nb, | |||
176 | return notifier_from_errno(ret); | 171 | return notifier_from_errno(ret); |
177 | } | 172 | } |
178 | 173 | ||
179 | static const struct clk_ops meson_clk_cpu_ops = { | 174 | const struct clk_ops meson_clk_cpu_ops = { |
180 | .recalc_rate = meson_clk_cpu_recalc_rate, | 175 | .recalc_rate = meson_clk_cpu_recalc_rate, |
181 | .round_rate = meson_clk_cpu_round_rate, | 176 | .round_rate = meson_clk_cpu_round_rate, |
182 | .set_rate = meson_clk_cpu_set_rate, | 177 | .set_rate = meson_clk_cpu_set_rate, |
183 | }; | 178 | }; |
184 | |||
185 | struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, | ||
186 | void __iomem *reg_base, | ||
187 | spinlock_t *lock) | ||
188 | { | ||
189 | struct clk *clk; | ||
190 | struct clk *pclk; | ||
191 | struct meson_clk_cpu *clk_cpu; | ||
192 | struct clk_init_data init; | ||
193 | int ret; | ||
194 | |||
195 | clk_cpu = kzalloc(sizeof(*clk_cpu), GFP_KERNEL); | ||
196 | if (!clk_cpu) | ||
197 | return ERR_PTR(-ENOMEM); | ||
198 | |||
199 | clk_cpu->base = reg_base; | ||
200 | clk_cpu->reg_off = clk_conf->reg_off; | ||
201 | clk_cpu->div_table = clk_conf->conf.div_table; | ||
202 | clk_cpu->clk_nb.notifier_call = meson_clk_cpu_notifier_cb; | ||
203 | |||
204 | init.name = clk_conf->clk_name; | ||
205 | init.ops = &meson_clk_cpu_ops; | ||
206 | init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE; | ||
207 | init.flags |= CLK_SET_RATE_PARENT; | ||
208 | init.parent_names = clk_conf->clks_parent; | ||
209 | init.num_parents = 1; | ||
210 | |||
211 | clk_cpu->hw.init = &init; | ||
212 | |||
213 | pclk = __clk_lookup(clk_conf->clks_parent[0]); | ||
214 | if (!pclk) { | ||
215 | pr_err("%s: could not lookup parent clock %s\n", | ||
216 | __func__, clk_conf->clks_parent[0]); | ||
217 | ret = -EINVAL; | ||
218 | goto free_clk; | ||
219 | } | ||
220 | |||
221 | ret = clk_notifier_register(pclk, &clk_cpu->clk_nb); | ||
222 | if (ret) { | ||
223 | pr_err("%s: failed to register clock notifier for %s\n", | ||
224 | __func__, clk_conf->clk_name); | ||
225 | goto free_clk; | ||
226 | } | ||
227 | |||
228 | clk = clk_register(NULL, &clk_cpu->hw); | ||
229 | if (IS_ERR(clk)) { | ||
230 | ret = PTR_ERR(clk); | ||
231 | goto unregister_clk_nb; | ||
232 | } | ||
233 | |||
234 | return clk; | ||
235 | |||
236 | unregister_clk_nb: | ||
237 | clk_notifier_unregister(pclk, &clk_cpu->clk_nb); | ||
238 | free_clk: | ||
239 | kfree(clk_cpu); | ||
240 | |||
241 | return ERR_PTR(ret); | ||
242 | } | ||
243 | |||
diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c index 275da2790063..0f965537b37f 100644 --- a/drivers/clk/meson/clkc.c +++ b/drivers/clk/meson/clkc.c | |||
@@ -140,10 +140,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs, | |||
140 | clk = meson_clk_register_composite(clk_conf, | 140 | clk = meson_clk_register_composite(clk_conf, |
141 | clk_base); | 141 | clk_base); |
142 | break; | 142 | break; |
143 | case CLK_CPU: | ||
144 | clk = meson_clk_register_cpu(clk_conf, clk_base, | ||
145 | &clk_lock); | ||
146 | break; | ||
147 | default: | 143 | default: |
148 | clk = NULL; | 144 | clk = NULL; |
149 | } | 145 | } |
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 97dd4d719a84..bfa5ae24930a 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h | |||
@@ -69,6 +69,14 @@ struct meson_clk_pll { | |||
69 | 69 | ||
70 | #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw) | 70 | #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw) |
71 | 71 | ||
72 | struct meson_clk_cpu { | ||
73 | struct clk_hw hw; | ||
74 | void __iomem *base; | ||
75 | u16 reg_off; | ||
76 | struct notifier_block clk_nb; | ||
77 | const struct clk_div_table *div_table; | ||
78 | }; | ||
79 | |||
72 | struct composite_conf { | 80 | struct composite_conf { |
73 | struct parm mux_parm; | 81 | struct parm mux_parm; |
74 | struct parm div_parm; | 82 | struct parm div_parm; |
@@ -84,7 +92,6 @@ struct composite_conf { | |||
84 | 92 | ||
85 | enum clk_type { | 93 | enum clk_type { |
86 | CLK_COMPOSITE, | 94 | CLK_COMPOSITE, |
87 | CLK_CPU, | ||
88 | }; | 95 | }; |
89 | 96 | ||
90 | struct clk_conf { | 97 | struct clk_conf { |
@@ -101,17 +108,6 @@ struct clk_conf { | |||
101 | } conf; | 108 | } conf; |
102 | }; | 109 | }; |
103 | 110 | ||
104 | #define CPU(_ro, _ci, _cn, _cp, _dt) \ | ||
105 | { \ | ||
106 | .reg_off = (_ro), \ | ||
107 | .clk_type = CLK_CPU, \ | ||
108 | .clk_id = (_ci), \ | ||
109 | .clk_name = (_cn), \ | ||
110 | .clks_parent = (_cp), \ | ||
111 | .num_parents = ARRAY_SIZE(_cp), \ | ||
112 | .conf.div_table = (_dt), \ | ||
113 | } \ | ||
114 | |||
115 | #define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c) \ | 111 | #define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c) \ |
116 | { \ | 112 | { \ |
117 | .reg_off = (_ro), \ | 113 | .reg_off = (_ro), \ |
@@ -127,8 +123,8 @@ struct clk_conf { | |||
127 | struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks); | 123 | struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks); |
128 | void meson_clk_register_clks(const struct clk_conf *clk_confs, | 124 | void meson_clk_register_clks(const struct clk_conf *clk_confs, |
129 | unsigned int nr_confs, void __iomem *clk_base); | 125 | unsigned int nr_confs, void __iomem *clk_base); |
130 | struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, | 126 | int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event, |
131 | void __iomem *reg_base, spinlock_t *lock); | 127 | void *data); |
132 | 128 | ||
133 | /* shared data */ | 129 | /* shared data */ |
134 | extern spinlock_t clk_lock; | 130 | extern spinlock_t clk_lock; |
@@ -136,5 +132,6 @@ extern spinlock_t clk_lock; | |||
136 | /* clk_ops */ | 132 | /* clk_ops */ |
137 | extern const struct clk_ops meson_clk_pll_ro_ops; | 133 | extern const struct clk_ops meson_clk_pll_ro_ops; |
138 | extern const struct clk_ops meson_clk_pll_ops; | 134 | extern const struct clk_ops meson_clk_pll_ops; |
135 | extern const struct clk_ops meson_clk_cpu_ops; | ||
139 | 136 | ||
140 | #endif /* __CLKC_H */ | 137 | #endif /* __CLKC_H */ |
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c index 6571e66ecc4e..94512b6ada25 100644 --- a/drivers/clk/meson/meson8b-clkc.c +++ b/drivers/clk/meson/meson8b-clkc.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * this program. If not, see <http://www.gnu.org/licenses/>. | 15 | * this program. If not, see <http://www.gnu.org/licenses/>. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/clk.h> | ||
18 | #include <linux/clk-provider.h> | 19 | #include <linux/clk-provider.h> |
19 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
20 | #include <linux/of.h> | 21 | #include <linux/of.h> |
@@ -110,7 +111,6 @@ static const struct clk_div_table cpu_div_table[] = { | |||
110 | { /* sentinel */ }, | 111 | { /* sentinel */ }, |
111 | }; | 112 | }; |
112 | 113 | ||
113 | PNAME(p_cpu_clk) = { "sys_pll" }; | ||
114 | PNAME(p_clk81) = { "fclk_div3", "fclk_div4", "fclk_div5" }; | 114 | PNAME(p_clk81) = { "fclk_div3", "fclk_div4", "fclk_div5" }; |
115 | PNAME(p_mali) = { "fclk_div3", "fclk_div4", "fclk_div5", | 115 | PNAME(p_mali) = { "fclk_div3", "fclk_div4", "fclk_div5", |
116 | "fclk_div7", "zero" }; | 116 | "fclk_div7", "zero" }; |
@@ -286,9 +286,19 @@ static struct clk_fixed_factor meson8b_fclk_div7 = { | |||
286 | }, | 286 | }, |
287 | }; | 287 | }; |
288 | 288 | ||
289 | static struct meson_clk_cpu meson8b_cpu_clk = { | ||
290 | .reg_off = MESON8B_REG_SYS_CPU_CNTL1, | ||
291 | .div_table = cpu_div_table, | ||
292 | .clk_nb.notifier_call = meson_clk_cpu_notifier_cb, | ||
293 | .hw.init = &(struct clk_init_data){ | ||
294 | .name = "cpu_clk", | ||
295 | .ops = &meson_clk_cpu_ops, | ||
296 | .parent_names = (const char *[]){ "sys_pll" }, | ||
297 | .num_parents = 1, | ||
298 | }, | ||
299 | }; | ||
300 | |||
289 | static const struct clk_conf meson8b_clk_confs[] __initconst = { | 301 | static const struct clk_conf meson8b_clk_confs[] __initconst = { |
290 | CPU(MESON8B_REG_SYS_CPU_CNTL1, CLKID_CPUCLK, "a5_clk", p_cpu_clk, | ||
291 | cpu_div_table), | ||
292 | COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81, | 302 | COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81, |
293 | CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf), | 303 | CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf), |
294 | COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali, | 304 | COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali, |
@@ -314,6 +324,7 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { | |||
314 | [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, | 324 | [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, |
315 | [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, | 325 | [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, |
316 | [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, | 326 | [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, |
327 | [CLKID_CPUCLK] = &meson8b_cpu_clk.hw, | ||
317 | }, | 328 | }, |
318 | .num = CLK_NR_CLKS, | 329 | .num = CLK_NR_CLKS, |
319 | }; | 330 | }; |
@@ -328,6 +339,8 @@ static void __init meson8b_clkc_init(struct device_node *np) | |||
328 | { | 339 | { |
329 | void __iomem *clk_base; | 340 | void __iomem *clk_base; |
330 | int ret, clkid, i; | 341 | int ret, clkid, i; |
342 | struct clk_hw *parent_hw; | ||
343 | struct clk *parent_clk; | ||
331 | 344 | ||
332 | if (!meson_clk_init(np, CLK_NR_CLKS)) | 345 | if (!meson_clk_init(np, CLK_NR_CLKS)) |
333 | return; | 346 | return; |
@@ -343,6 +356,9 @@ static void __init meson8b_clkc_init(struct device_node *np) | |||
343 | for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) | 356 | for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) |
344 | meson8b_clk_plls[i]->base = clk_base; | 357 | meson8b_clk_plls[i]->base = clk_base; |
345 | 358 | ||
359 | /* Populate the base address for CPU clk */ | ||
360 | meson8b_cpu_clk.base = clk_base; | ||
361 | |||
346 | /* | 362 | /* |
347 | * register all clks | 363 | * register all clks |
348 | * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 | 364 | * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 |
@@ -358,12 +374,37 @@ static void __init meson8b_clkc_init(struct device_node *np) | |||
358 | goto unregister; | 374 | goto unregister; |
359 | } | 375 | } |
360 | 376 | ||
377 | /* | ||
378 | * Register CPU clk notifier | ||
379 | * | ||
380 | * FIXME this is wrong for a lot of reasons. First, the muxes should be | ||
381 | * struct clk_hw objects. Second, we shouldn't program the muxes in | ||
382 | * notifier handlers. The tricky programming sequence will be handled | ||
383 | * by the forthcoming coordinated clock rates mechanism once that | ||
384 | * feature is released. | ||
385 | * | ||
386 | * Furthermore, looking up the parent this way is terrible. At some | ||
387 | * point we will stop allocating a default struct clk when registering | ||
388 | * a new clk_hw, and this hack will no longer work. Releasing the ccr | ||
389 | * feature before that time solves the problem :-) | ||
390 | */ | ||
391 | parent_hw = clk_hw_get_parent(&meson8b_cpu_clk.hw); | ||
392 | parent_clk = parent_hw->clk; | ||
393 | ret = clk_notifier_register(parent_clk, &meson8b_cpu_clk.clk_nb); | ||
394 | if (ret) { | ||
395 | pr_err("%s: failed to register clock notifier for cpu_clk\n", | ||
396 | __func__); | ||
397 | goto unregister_clk_nb; | ||
398 | } | ||
399 | |||
361 | meson_clk_register_clks(meson8b_clk_confs, | 400 | meson_clk_register_clks(meson8b_clk_confs, |
362 | ARRAY_SIZE(meson8b_clk_confs), | 401 | ARRAY_SIZE(meson8b_clk_confs), |
363 | clk_base); | 402 | clk_base); |
364 | return; | 403 | return; |
365 | 404 | ||
366 | /* FIXME remove after converting to platform_driver/devm_clk_register */ | 405 | /* FIXME remove after converting to platform_driver/devm_clk_register */ |
406 | unregister_clk_nb: | ||
407 | clk_notifier_unregister(parent_clk, &meson8b_a5_clk.clk_nb); | ||
367 | unregister: | 408 | unregister: |
368 | for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--) | 409 | for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--) |
369 | clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]); | 410 | clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]); |