Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+59 -90
+4 -69
drivers/clk/meson/clk-cpu.c
··· 51 51 52 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 54 #define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw) 62 55 #define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb) 63 56 ··· 112 119 return parent_rate / div; 113 120 } 114 121 122 + /* FIXME MUX1 & MUX2 should be struct clk_hw objects */ 115 123 static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu, 116 124 struct clk_notifier_data *ndata) 117 125 { ··· 134 140 return 0; 135 141 } 136 142 143 + /* FIXME MUX1 & MUX2 should be struct clk_hw objects */ 137 144 static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu, 138 145 struct clk_notifier_data *ndata) 139 146 { ··· 156 161 * PLL clock is to be changed. We use the xtal input as temporary parent 157 162 * while the PLL frequency is stabilized. 158 163 */ 159 - static int meson_clk_cpu_notifier_cb(struct notifier_block *nb, 164 + int meson_clk_cpu_notifier_cb(struct notifier_block *nb, 160 165 unsigned long event, void *data) 161 166 { 162 167 struct clk_notifier_data *ndata = data; ··· 171 176 return notifier_from_errno(ret); 172 177 } 173 178 174 - static const struct clk_ops meson_clk_cpu_ops = { 179 + const struct clk_ops meson_clk_cpu_ops = { 175 180 .recalc_rate = meson_clk_cpu_recalc_rate, 176 181 .round_rate = meson_clk_cpu_round_rate, 177 182 .set_rate = meson_clk_cpu_set_rate, 178 183 }; 179 - 180 - struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, 181 - void __iomem *reg_base, 182 - spinlock_t *lock) 183 - { 184 - struct clk *clk; 185 - struct clk *pclk; 186 - struct meson_clk_cpu *clk_cpu; 187 - struct clk_init_data init; 188 - int ret; 189 - 190 - clk_cpu = kzalloc(sizeof(*clk_cpu), GFP_KERNEL); 191 - if (!clk_cpu) 192 - return ERR_PTR(-ENOMEM); 193 - 194 - clk_cpu->base = reg_base; 195 - clk_cpu->reg_off = clk_conf->reg_off; 196 - clk_cpu->div_table = clk_conf->conf.div_table; 197 - clk_cpu->clk_nb.notifier_call = meson_clk_cpu_notifier_cb; 198 - 199 - init.name = clk_conf->clk_name; 200 - init.ops = &meson_clk_cpu_ops; 201 - init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE; 202 - init.flags |= CLK_SET_RATE_PARENT; 203 - init.parent_names = clk_conf->clks_parent; 204 - init.num_parents = 1; 205 - 206 - clk_cpu->hw.init = &init; 207 - 208 - pclk = __clk_lookup(clk_conf->clks_parent[0]); 209 - if (!pclk) { 210 - pr_err("%s: could not lookup parent clock %s\n", 211 - __func__, clk_conf->clks_parent[0]); 212 - ret = -EINVAL; 213 - goto free_clk; 214 - } 215 - 216 - ret = clk_notifier_register(pclk, &clk_cpu->clk_nb); 217 - if (ret) { 218 - pr_err("%s: failed to register clock notifier for %s\n", 219 - __func__, clk_conf->clk_name); 220 - goto free_clk; 221 - } 222 - 223 - clk = clk_register(NULL, &clk_cpu->hw); 224 - if (IS_ERR(clk)) { 225 - ret = PTR_ERR(clk); 226 - goto unregister_clk_nb; 227 - } 228 - 229 - return clk; 230 - 231 - unregister_clk_nb: 232 - clk_notifier_unregister(pclk, &clk_cpu->clk_nb); 233 - free_clk: 234 - kfree(clk_cpu); 235 - 236 - return ERR_PTR(ret); 237 - } 238 -
-4
drivers/clk/meson/clkc.c
··· 140 140 clk = meson_clk_register_composite(clk_conf, 141 141 clk_base); 142 142 break; 143 - case CLK_CPU: 144 - clk = meson_clk_register_cpu(clk_conf, clk_base, 145 - &clk_lock); 146 - break; 147 143 default: 148 144 clk = NULL; 149 145 }
+11 -14
drivers/clk/meson/clkc.h
··· 69 69 70 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 80 struct composite_conf { 73 81 struct parm mux_parm; 74 82 struct parm div_parm; ··· 92 84 93 85 enum clk_type { 94 86 CLK_COMPOSITE, 95 - CLK_CPU, 96 87 }; 97 88 98 89 struct clk_conf { ··· 108 101 } conf; 109 102 }; 110 103 111 - #define CPU(_ro, _ci, _cn, _cp, _dt) \ 112 - { \ 113 - .reg_off = (_ro), \ 114 - .clk_type = CLK_CPU, \ 115 - .clk_id = (_ci), \ 116 - .clk_name = (_cn), \ 117 - .clks_parent = (_cp), \ 118 - .num_parents = ARRAY_SIZE(_cp), \ 119 - .conf.div_table = (_dt), \ 120 - } \ 121 - 122 104 #define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c) \ 123 105 { \ 124 106 .reg_off = (_ro), \ ··· 123 127 struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks); 124 128 void meson_clk_register_clks(const struct clk_conf *clk_confs, 125 129 unsigned int nr_confs, void __iomem *clk_base); 126 - struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, 127 - void __iomem *reg_base, spinlock_t *lock); 130 + int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event, 131 + void *data); 128 132 129 133 /* shared data */ 130 134 extern spinlock_t clk_lock; ··· 132 136 /* clk_ops */ 133 137 extern const struct clk_ops meson_clk_pll_ro_ops; 134 138 extern const struct clk_ops meson_clk_pll_ops; 139 + extern const struct clk_ops meson_clk_cpu_ops; 135 140 136 141 #endif /* __CLKC_H */
+44 -3
drivers/clk/meson/meson8b-clkc.c
··· 15 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 16 */ 17 17 18 + #include <linux/clk.h> 18 19 #include <linux/clk-provider.h> 19 20 #include <linux/kernel.h> 20 21 #include <linux/of.h> ··· 111 110 { /* sentinel */ }, 112 111 }; 113 112 114 - PNAME(p_cpu_clk) = { "sys_pll" }; 115 113 PNAME(p_clk81) = { "fclk_div3", "fclk_div4", "fclk_div5" }; 116 114 PNAME(p_mali) = { "fclk_div3", "fclk_div4", "fclk_div5", 117 115 "fclk_div7", "zero" }; ··· 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 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 302 COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81, 293 303 CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf), 294 304 COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali, ··· 324 314 [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, 325 315 [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, 326 316 [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, 317 + [CLKID_CPUCLK] = &meson8b_cpu_clk.hw, 327 318 }, 328 319 .num = CLK_NR_CLKS, 329 320 }; ··· 339 328 { 340 329 void __iomem *clk_base; 341 330 int ret, clkid, i; 331 + struct clk_hw *parent_hw; 332 + struct clk *parent_clk; 342 333 343 334 if (!meson_clk_init(np, CLK_NR_CLKS)) 344 335 return; ··· 355 342 /* Populate base address for PLLs */ 356 343 for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) 357 344 meson8b_clk_plls[i]->base = clk_base; 345 + 346 + /* Populate the base address for CPU clk */ 347 + meson8b_cpu_clk.base = clk_base; 358 348 359 349 /* 360 350 * register all clks ··· 374 358 goto unregister; 375 359 } 376 360 361 + /* 362 + * Register CPU clk notifier 363 + * 364 + * FIXME this is wrong for a lot of reasons. First, the muxes should be 365 + * struct clk_hw objects. Second, we shouldn't program the muxes in 366 + * notifier handlers. The tricky programming sequence will be handled 367 + * by the forthcoming coordinated clock rates mechanism once that 368 + * feature is released. 369 + * 370 + * Furthermore, looking up the parent this way is terrible. At some 371 + * point we will stop allocating a default struct clk when registering 372 + * a new clk_hw, and this hack will no longer work. Releasing the ccr 373 + * feature before that time solves the problem :-) 374 + */ 375 + parent_hw = clk_hw_get_parent(&meson8b_cpu_clk.hw); 376 + parent_clk = parent_hw->clk; 377 + ret = clk_notifier_register(parent_clk, &meson8b_cpu_clk.clk_nb); 378 + if (ret) { 379 + pr_err("%s: failed to register clock notifier for cpu_clk\n", 380 + __func__); 381 + goto unregister_clk_nb; 382 + } 383 + 377 384 meson_clk_register_clks(meson8b_clk_confs, 378 385 ARRAY_SIZE(meson8b_clk_confs), 379 386 clk_base); 380 387 return; 381 388 382 389 /* FIXME remove after converting to platform_driver/devm_clk_register */ 390 + unregister_clk_nb: 391 + clk_notifier_unregister(parent_clk, &meson8b_a5_clk.clk_nb); 383 392 unregister: 384 393 for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--) 385 394 clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]);