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

clk: amlogic: get regmap with clk_regmap_init

Add clk_regmap_init() and use it with all clock types which derive from
clk_regmap. This helps initialise clk_regmap clocks without requiring
tables to keep track of the clock using this type.

The way it is done couples clk_regmap with the controllers, which is not
ideal. This is a temporary solution to get rid of the tables. The situation
will eventually be improved.

Link: https://lore.kernel.org/r/20250623-amlogic-clk-drop-clk-regmap-tables-v4-1-ff04918211cc@baylibre.com
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>

+89
+1
drivers/clk/meson/Kconfig
··· 5 5 config COMMON_CLK_MESON_REGMAP 6 6 tristate 7 7 select REGMAP 8 + select MFD_SYSCON 8 9 9 10 config COMMON_CLK_MESON_DUALDIV 10 11 tristate
+1
drivers/clk/meson/clk-cpu-dyndiv.c
··· 61 61 }; 62 62 63 63 const struct clk_ops meson_clk_cpu_dyndiv_ops = { 64 + .init = clk_regmap_init, 64 65 .recalc_rate = meson_clk_cpu_dyndiv_recalc_rate, 65 66 .determine_rate = meson_clk_cpu_dyndiv_determine_rate, 66 67 .set_rate = meson_clk_cpu_dyndiv_set_rate,
+2
drivers/clk/meson/clk-dualdiv.c
··· 126 126 } 127 127 128 128 const struct clk_ops meson_clk_dualdiv_ops = { 129 + .init = clk_regmap_init, 129 130 .recalc_rate = meson_clk_dualdiv_recalc_rate, 130 131 .determine_rate = meson_clk_dualdiv_determine_rate, 131 132 .set_rate = meson_clk_dualdiv_set_rate, ··· 134 133 EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ops, "CLK_MESON"); 135 134 136 135 const struct clk_ops meson_clk_dualdiv_ro_ops = { 136 + .init = clk_regmap_init, 137 137 .recalc_rate = meson_clk_dualdiv_recalc_rate, 138 138 }; 139 139 EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ro_ops, "CLK_MESON");
+6
drivers/clk/meson/clk-mpll.c
··· 128 128 { 129 129 struct clk_regmap *clk = to_clk_regmap(hw); 130 130 struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk); 131 + int ret; 132 + 133 + ret = clk_regmap_init(hw); 134 + if (ret) 135 + return ret; 131 136 132 137 if (mpll->init_count) 133 138 regmap_multi_reg_write(clk->map, mpll->init_regs, ··· 156 151 } 157 152 158 153 const struct clk_ops meson_clk_mpll_ro_ops = { 154 + .init = clk_regmap_init, 159 155 .recalc_rate = mpll_recalc_rate, 160 156 .determine_rate = mpll_determine_rate, 161 157 };
+11
drivers/clk/meson/clk-phase.c
··· 58 58 } 59 59 60 60 const struct clk_ops meson_clk_phase_ops = { 61 + .init = clk_regmap_init, 61 62 .get_phase = meson_clk_phase_get_phase, 62 63 .set_phase = meson_clk_phase_set_phase, 63 64 }; ··· 84 83 struct clk_regmap *clk = to_clk_regmap(hw); 85 84 struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk); 86 85 unsigned int val; 86 + int ret; 87 + 88 + ret = clk_regmap_init(hw); 89 + if (ret) 90 + return ret; 87 91 88 92 /* Get phase 0 and sync it to phase 1 and 2 */ 89 93 val = meson_parm_read(clk->map, &tph->ph0); ··· 148 142 struct clk_regmap *clk = to_clk_regmap(hw); 149 143 struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk); 150 144 unsigned int val; 145 + int ret; 146 + 147 + ret = clk_regmap_init(hw); 148 + if (ret) 149 + return ret; 151 150 152 151 /* Get phase and sync the inverted value to ws */ 153 152 val = meson_parm_read(clk->map, &tph->ph);
+7
drivers/clk/meson/clk-pll.c
··· 311 311 { 312 312 struct clk_regmap *clk = to_clk_regmap(hw); 313 313 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); 314 + int ret; 315 + 316 + ret = clk_regmap_init(hw); 317 + if (ret) 318 + return ret; 314 319 315 320 /* 316 321 * Keep the clock running, which was already initialized and enabled ··· 473 468 * the other ops except set_rate since the rate is fixed. 474 469 */ 475 470 const struct clk_ops meson_clk_pcie_pll_ops = { 471 + .init = clk_regmap_init, 476 472 .recalc_rate = meson_clk_pll_recalc_rate, 477 473 .determine_rate = meson_clk_pll_determine_rate, 478 474 .is_enabled = meson_clk_pll_is_enabled, ··· 494 488 EXPORT_SYMBOL_NS_GPL(meson_clk_pll_ops, "CLK_MESON"); 495 489 496 490 const struct clk_ops meson_clk_pll_ro_ops = { 491 + .init = clk_regmap_init, 497 492 .recalc_rate = meson_clk_pll_recalc_rate, 498 493 .is_enabled = meson_clk_pll_is_enabled, 499 494 };
+49
drivers/clk/meson/clk-regmap.c
··· 4 4 * Author: Jerome Brunet <jbrunet@baylibre.com> 5 5 */ 6 6 7 + #include <linux/device.h> 7 8 #include <linux/module.h> 9 + #include <linux/mfd/syscon.h> 8 10 #include "clk-regmap.h" 11 + 12 + int clk_regmap_init(struct clk_hw *hw) 13 + { 14 + struct clk_regmap *clk = to_clk_regmap(hw); 15 + struct device_node *np, *parent_np; 16 + struct device *dev; 17 + 18 + /* Allow regmap to be preset as it was historically done */ 19 + if (clk->map) 20 + return 0; 21 + 22 + /* 23 + * FIXME: what follows couples the controller implementation 24 + * and clk_regmap clock type. This situation is not desirable 25 + * but temporary, until the controller is able to register 26 + * a hook to initialize a clock type 27 + */ 28 + 29 + /* Check the usual dev enabled controller with an basic IO regmap */ 30 + dev = clk_hw_get_dev(hw); 31 + if (dev) { 32 + clk->map = dev_get_regmap(dev, NULL); 33 + if (clk->map) 34 + return 0; 35 + } 36 + 37 + /* Move on to early and syscon based controllers */ 38 + np = clk_hw_get_of_node(hw); 39 + if (np) { 40 + parent_np = of_get_parent(np); 41 + clk->map = syscon_node_to_regmap(parent_np); 42 + of_node_put(parent_np); 43 + 44 + if (!IS_ERR_OR_NULL(clk->map)) 45 + return 0; 46 + } 47 + 48 + /* Bail out if regmap can't be found */ 49 + return -EINVAL; 50 + } 51 + EXPORT_SYMBOL_NS_GPL(clk_regmap_init, "CLK_MESON"); 9 52 10 53 static int clk_regmap_gate_endisable(struct clk_hw *hw, int enable) 11 54 { ··· 88 45 } 89 46 90 47 const struct clk_ops clk_regmap_gate_ops = { 48 + .init = clk_regmap_init, 91 49 .enable = clk_regmap_gate_enable, 92 50 .disable = clk_regmap_gate_disable, 93 51 .is_enabled = clk_regmap_gate_is_enabled, ··· 96 52 EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ops, "CLK_MESON"); 97 53 98 54 const struct clk_ops clk_regmap_gate_ro_ops = { 55 + .init = clk_regmap_init, 99 56 .is_enabled = clk_regmap_gate_is_enabled, 100 57 }; 101 58 EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ro_ops, "CLK_MESON"); ··· 166 121 /* Would prefer clk_regmap_div_ro_ops but clashes with qcom */ 167 122 168 123 const struct clk_ops clk_regmap_divider_ops = { 124 + .init = clk_regmap_init, 169 125 .recalc_rate = clk_regmap_div_recalc_rate, 170 126 .determine_rate = clk_regmap_div_determine_rate, 171 127 .set_rate = clk_regmap_div_set_rate, ··· 174 128 EXPORT_SYMBOL_NS_GPL(clk_regmap_divider_ops, "CLK_MESON"); 175 129 176 130 const struct clk_ops clk_regmap_divider_ro_ops = { 131 + .init = clk_regmap_init, 177 132 .recalc_rate = clk_regmap_div_recalc_rate, 178 133 .determine_rate = clk_regmap_div_determine_rate, 179 134 }; ··· 217 170 } 218 171 219 172 const struct clk_ops clk_regmap_mux_ops = { 173 + .init = clk_regmap_init, 220 174 .get_parent = clk_regmap_mux_get_parent, 221 175 .set_parent = clk_regmap_mux_set_parent, 222 176 .determine_rate = clk_regmap_mux_determine_rate, ··· 225 177 EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ops, "CLK_MESON"); 226 178 227 179 const struct clk_ops clk_regmap_mux_ro_ops = { 180 + .init = clk_regmap_init, 228 181 .get_parent = clk_regmap_mux_get_parent, 229 182 }; 230 183 EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ro_ops, "CLK_MESON");
+4
drivers/clk/meson/clk-regmap.h
··· 7 7 #ifndef __CLK_REGMAP_H 8 8 #define __CLK_REGMAP_H 9 9 10 + #include <linux/device.h> 10 11 #include <linux/clk-provider.h> 11 12 #include <linux/regmap.h> 12 13 ··· 31 30 { 32 31 return container_of(hw, struct clk_regmap, hw); 33 32 } 33 + 34 + /* clk_regmap init op to get and cache regmap from the controllers */ 35 + int clk_regmap_init(struct clk_hw *hw); 34 36 35 37 /** 36 38 * struct clk_regmap_gate_data - regmap backed gate specific data
+5
drivers/clk/meson/sclk-div.c
··· 222 222 struct clk_regmap *clk = to_clk_regmap(hw); 223 223 struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 224 224 unsigned int val; 225 + int ret; 226 + 227 + ret = clk_regmap_init(hw); 228 + if (ret) 229 + return ret; 225 230 226 231 val = meson_parm_read(clk->map, &sclk->div); 227 232
+2
drivers/clk/meson/vclk.c
··· 45 45 } 46 46 47 47 const struct clk_ops meson_vclk_gate_ops = { 48 + .init = clk_regmap_init, 48 49 .enable = meson_vclk_gate_enable, 49 50 .disable = meson_vclk_gate_disable, 50 51 .is_enabled = meson_vclk_gate_is_enabled, ··· 128 127 } 129 128 130 129 const struct clk_ops meson_vclk_div_ops = { 130 + .init = clk_regmap_init, 131 131 .recalc_rate = meson_vclk_div_recalc_rate, 132 132 .determine_rate = meson_vclk_div_determine_rate, 133 133 .set_rate = meson_vclk_div_set_rate,
+1
drivers/clk/meson/vid-pll-div.c
··· 90 90 } 91 91 92 92 const struct clk_ops meson_vid_pll_div_ro_ops = { 93 + .init = clk_regmap_init, 93 94 .recalc_rate = meson_vid_pll_div_recalc_rate, 94 95 }; 95 96 EXPORT_SYMBOL_NS_GPL(meson_vid_pll_div_ro_ops, "CLK_MESON");