6666#define DIV_MASK_ALL GENMASK(31, 0)
6767#define MUX_MASK GENMASK(2, 0)
6868
69+ struct exynos_cpuclk ;
70+
71+ typedef int (* exynos_rate_change_fn_t )(struct clk_notifier_data * ndata ,
72+ struct exynos_cpuclk * cpuclk );
73+
6974/**
7075 * struct exynos_cpuclk - information about clock supplied to a CPU core
7176 * @hw: handle between CCF and CPU clock
7883 * @clk_nb: clock notifier registered for changes in clock speed of the
7984 * primary parent clock
8085 * @flags: configuration flags for the CPU clock
86+ * @pre_rate_cb: callback to run before CPU clock rate change
87+ * @post_rate_cb: callback to run after CPU clock rate change
8188 *
8289 * This structure holds information required for programming the CPU clock for
8390 * various clock speeds.
@@ -91,6 +98,9 @@ struct exynos_cpuclk {
9198 const unsigned long num_cfgs ;
9299 struct notifier_block clk_nb ;
93100 unsigned long flags ;
101+
102+ exynos_rate_change_fn_t pre_rate_cb ;
103+ exynos_rate_change_fn_t post_rate_cb ;
94104};
95105
96106/*
@@ -178,9 +188,10 @@ static void exynos_set_safe_div(void __iomem *base, unsigned long div,
178188
179189/* handler for pre-rate change notification from parent clock */
180190static int exynos_cpuclk_pre_rate_change (struct clk_notifier_data * ndata ,
181- struct exynos_cpuclk * cpuclk , void __iomem * base )
191+ struct exynos_cpuclk * cpuclk )
182192{
183193 const struct exynos_cpuclk_cfg_data * cfg_data = cpuclk -> cfg ;
194+ void __iomem * base = cpuclk -> ctrl_base ;
184195 unsigned long alt_prate = clk_hw_get_rate (cpuclk -> alt_parent );
185196 unsigned long div0 , div1 = 0 , mux_reg ;
186197 unsigned long flags ;
@@ -255,9 +266,10 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
255266
256267/* handler for post-rate change notification from parent clock */
257268static int exynos_cpuclk_post_rate_change (struct clk_notifier_data * ndata ,
258- struct exynos_cpuclk * cpuclk , void __iomem * base )
269+ struct exynos_cpuclk * cpuclk )
259270{
260271 const struct exynos_cpuclk_cfg_data * cfg_data = cpuclk -> cfg ;
272+ void __iomem * base = cpuclk -> ctrl_base ;
261273 unsigned long div = 0 , div_mask = DIV_MASK ;
262274 unsigned long mux_reg ;
263275 unsigned long flags ;
@@ -306,9 +318,10 @@ static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
306318
307319/* handler for pre-rate change notification from parent clock */
308320static int exynos5433_cpuclk_pre_rate_change (struct clk_notifier_data * ndata ,
309- struct exynos_cpuclk * cpuclk , void __iomem * base )
321+ struct exynos_cpuclk * cpuclk )
310322{
311323 const struct exynos_cpuclk_cfg_data * cfg_data = cpuclk -> cfg ;
324+ void __iomem * base = cpuclk -> ctrl_base ;
312325 unsigned long alt_prate = clk_hw_get_rate (cpuclk -> alt_parent );
313326 unsigned long div0 , div1 = 0 , mux_reg ;
314327 unsigned long flags ;
@@ -366,8 +379,9 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
366379
367380/* handler for post-rate change notification from parent clock */
368381static int exynos5433_cpuclk_post_rate_change (struct clk_notifier_data * ndata ,
369- struct exynos_cpuclk * cpuclk , void __iomem * base )
382+ struct exynos_cpuclk * cpuclk )
370383{
384+ void __iomem * base = cpuclk -> ctrl_base ;
371385 unsigned long div = 0 , div_mask = DIV_MASK ;
372386 unsigned long mux_reg ;
373387 unsigned long flags ;
@@ -393,39 +407,14 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
393407{
394408 struct clk_notifier_data * ndata = data ;
395409 struct exynos_cpuclk * cpuclk ;
396- void __iomem * base ;
397410 int err = 0 ;
398411
399412 cpuclk = container_of (nb , struct exynos_cpuclk , clk_nb );
400- base = cpuclk -> ctrl_base ;
401413
402414 if (event == PRE_RATE_CHANGE )
403- err = exynos_cpuclk_pre_rate_change (ndata , cpuclk , base );
415+ err = cpuclk -> pre_rate_cb (ndata , cpuclk );
404416 else if (event == POST_RATE_CHANGE )
405- err = exynos_cpuclk_post_rate_change (ndata , cpuclk , base );
406-
407- return notifier_from_errno (err );
408- }
409-
410- /*
411- * This notifier function is called for the pre-rate and post-rate change
412- * notifications of the parent clock of cpuclk.
413- */
414- static int exynos5433_cpuclk_notifier_cb (struct notifier_block * nb ,
415- unsigned long event , void * data )
416- {
417- struct clk_notifier_data * ndata = data ;
418- struct exynos_cpuclk * cpuclk ;
419- void __iomem * base ;
420- int err = 0 ;
421-
422- cpuclk = container_of (nb , struct exynos_cpuclk , clk_nb );
423- base = cpuclk -> ctrl_base ;
424-
425- if (event == PRE_RATE_CHANGE )
426- err = exynos5433_cpuclk_pre_rate_change (ndata , cpuclk , base );
427- else if (event == POST_RATE_CHANGE )
428- err = exynos5433_cpuclk_post_rate_change (ndata , cpuclk , base );
417+ err = cpuclk -> post_rate_cb (ndata , cpuclk );
429418
430419 return notifier_from_errno (err );
431420}
@@ -467,10 +456,14 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
467456 cpuclk -> ctrl_base = ctx -> reg_base + clk_data -> offset ;
468457 cpuclk -> lock = & ctx -> lock ;
469458 cpuclk -> flags = clk_data -> flags ;
470- if (clk_data -> flags & CLK_CPU_HAS_E5433_REGS_LAYOUT )
471- cpuclk -> clk_nb .notifier_call = exynos5433_cpuclk_notifier_cb ;
472- else
473- cpuclk -> clk_nb .notifier_call = exynos_cpuclk_notifier_cb ;
459+ cpuclk -> clk_nb .notifier_call = exynos_cpuclk_notifier_cb ;
460+ if (clk_data -> flags & CLK_CPU_HAS_E5433_REGS_LAYOUT ) {
461+ cpuclk -> pre_rate_cb = exynos5433_cpuclk_pre_rate_change ;
462+ cpuclk -> post_rate_cb = exynos5433_cpuclk_post_rate_change ;
463+ } else {
464+ cpuclk -> pre_rate_cb = exynos_cpuclk_pre_rate_change ;
465+ cpuclk -> post_rate_cb = exynos_cpuclk_post_rate_change ;
466+ }
474467
475468 ret = clk_notifier_register (parent -> clk , & cpuclk -> clk_nb );
476469 if (ret ) {
0 commit comments