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

Configure Feed

Select the types of activity you want to include in your feed.

clk: sunxi: register factors clocks behind composite

This commit reworks factors clock registration to be done behind a
composite clock. This allows us to additionally add a gate, mux or
divisors, as it will be needed by some future PLLs.

Signed-off-by: Emilio López <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Mike Turquette <mturquette@linaro.org>

+76 -73
+1 -62
drivers/clk/sunxi/clk-factors.c
··· 30 30 * parent - fixed parent. No clk_set_parent support 31 31 */ 32 32 33 - struct clk_factors { 34 - struct clk_hw hw; 35 - void __iomem *reg; 36 - struct clk_factors_config *config; 37 - void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); 38 - spinlock_t *lock; 39 - }; 40 - 41 33 #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw) 42 34 43 35 #define SETMASK(len, pos) (((1U << (len)) - 1) << (pos)) ··· 112 120 return 0; 113 121 } 114 122 115 - static const struct clk_ops clk_factors_ops = { 123 + const struct clk_ops clk_factors_ops = { 116 124 .recalc_rate = clk_factors_recalc_rate, 117 125 .round_rate = clk_factors_round_rate, 118 126 .set_rate = clk_factors_set_rate, 119 127 }; 120 - 121 - /** 122 - * clk_register_factors - register a factors clock with 123 - * the clock framework 124 - * @dev: device registering this clock 125 - * @name: name of this clock 126 - * @parent_name: name of clock's parent 127 - * @flags: framework-specific flags 128 - * @reg: register address to adjust factors 129 - * @config: shift and width of factors n, k, m and p 130 - * @get_factors: function to calculate the factors for a given frequency 131 - * @lock: shared register lock for this clock 132 - */ 133 - struct clk *clk_register_factors(struct device *dev, const char *name, 134 - const char *parent_name, 135 - unsigned long flags, void __iomem *reg, 136 - struct clk_factors_config *config, 137 - void (*get_factors)(u32 *rate, u32 parent, 138 - u8 *n, u8 *k, u8 *m, u8 *p), 139 - spinlock_t *lock) 140 - { 141 - struct clk_factors *factors; 142 - struct clk *clk; 143 - struct clk_init_data init; 144 - 145 - /* allocate the factors */ 146 - factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); 147 - if (!factors) { 148 - pr_err("%s: could not allocate factors clk\n", __func__); 149 - return ERR_PTR(-ENOMEM); 150 - } 151 - 152 - init.name = name; 153 - init.ops = &clk_factors_ops; 154 - init.flags = flags; 155 - init.parent_names = (parent_name ? &parent_name : NULL); 156 - init.num_parents = (parent_name ? 1 : 0); 157 - 158 - /* struct clk_factors assignments */ 159 - factors->reg = reg; 160 - factors->config = config; 161 - factors->lock = lock; 162 - factors->hw.init = &init; 163 - factors->get_factors = get_factors; 164 - 165 - /* register the clock */ 166 - clk = clk_register(dev, &factors->hw); 167 - 168 - if (IS_ERR(clk)) 169 - kfree(factors); 170 - 171 - return clk; 172 - }
+9 -7
drivers/clk/sunxi/clk-factors.h
··· 17 17 u8 pwidth; 18 18 }; 19 19 20 - struct clk *clk_register_factors(struct device *dev, const char *name, 21 - const char *parent_name, 22 - unsigned long flags, void __iomem *reg, 23 - struct clk_factors_config *config, 24 - void (*get_factors) (u32 *rate, u32 parent_rate, 25 - u8 *n, u8 *k, u8 *m, u8 *p), 26 - spinlock_t *lock); 20 + struct clk_factors { 21 + struct clk_hw hw; 22 + void __iomem *reg; 23 + struct clk_factors_config *config; 24 + void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); 25 + spinlock_t *lock; 26 + }; 27 + 28 + extern const struct clk_ops clk_factors_ops; 27 29 #endif
+66 -4
drivers/clk/sunxi/clk-sunxi.c
··· 23 23 24 24 static DEFINE_SPINLOCK(clk_lock); 25 25 26 + /* Maximum number of parents our clocks have */ 27 + #define SUNXI_MAX_PARENTS 5 28 + 26 29 /** 27 30 * sun4i_osc_clk_setup() - Setup function for gatable oscillator 28 31 */ ··· 264 261 * sunxi_factors_clk_setup() - Setup function for factor clocks 265 262 */ 266 263 264 + #define SUNXI_FACTORS_MUX_MASK 0x3 265 + 267 266 struct factors_data { 267 + int enable; 268 + int mux; 268 269 struct clk_factors_config *table; 269 270 void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); 270 271 }; ··· 319 312 struct factors_data *data) 320 313 { 321 314 struct clk *clk; 315 + struct clk_factors *factors; 316 + struct clk_gate *gate = NULL; 317 + struct clk_mux *mux = NULL; 318 + struct clk_hw *gate_hw = NULL; 319 + struct clk_hw *mux_hw = NULL; 322 320 const char *clk_name = node->name; 323 - const char *parent; 321 + const char *parents[SUNXI_MAX_PARENTS]; 324 322 void *reg; 323 + int i = 0; 325 324 326 325 reg = of_iomap(node, 0); 327 326 328 - parent = of_clk_get_parent_name(node, 0); 327 + /* if we have a mux, we will have >1 parents */ 328 + while (i < SUNXI_MAX_PARENTS && 329 + (parents[i] = of_clk_get_parent_name(node, i)) != NULL) 330 + i++; 329 331 330 - clk = clk_register_factors(NULL, clk_name, parent, 0, reg, 331 - data->table, data->getter, &clk_lock); 332 + factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); 333 + if (!factors) 334 + return; 335 + 336 + /* Add a gate if this factor clock can be gated */ 337 + if (data->enable) { 338 + gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 339 + if (!gate) { 340 + kfree(factors); 341 + return; 342 + } 343 + 344 + /* set up gate properties */ 345 + gate->reg = reg; 346 + gate->bit_idx = data->enable; 347 + gate->lock = &clk_lock; 348 + gate_hw = &gate->hw; 349 + } 350 + 351 + /* Add a mux if this factor clock can be muxed */ 352 + if (data->mux) { 353 + mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); 354 + if (!mux) { 355 + kfree(factors); 356 + kfree(gate); 357 + return; 358 + } 359 + 360 + /* set up gate properties */ 361 + mux->reg = reg; 362 + mux->shift = data->mux; 363 + mux->mask = SUNXI_FACTORS_MUX_MASK; 364 + mux->lock = &clk_lock; 365 + mux_hw = &mux->hw; 366 + } 367 + 368 + /* set up factors properties */ 369 + factors->reg = reg; 370 + factors->config = data->table; 371 + factors->get_factors = data->getter; 372 + factors->lock = &clk_lock; 373 + 374 + clk = clk_register_composite(NULL, clk_name, 375 + parents, i, 376 + mux_hw, &clk_mux_ops, 377 + &factors->hw, &clk_factors_ops, 378 + gate_hw, &clk_gate_ops, 379 + i ? 0 : CLK_IS_ROOT); 332 380 333 381 if (!IS_ERR(clk)) { 334 382 of_clk_add_provider(node, of_clk_src_simple_get, clk);