66
66
#define DIV_MASK_ALL GENMASK(31, 0)
67
67
#define MUX_MASK GENMASK(2, 0)
68
68
69
+ struct exynos_cpuclk ;
70
+
71
+ typedef int (* exynos_rate_change_fn_t )(struct clk_notifier_data * ndata ,
72
+ struct exynos_cpuclk * cpuclk );
73
+
69
74
/**
70
75
* struct exynos_cpuclk - information about clock supplied to a CPU core
71
76
* @hw: handle between CCF and CPU clock
78
83
* @clk_nb: clock notifier registered for changes in clock speed of the
79
84
* primary parent clock
80
85
* @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
81
88
*
82
89
* This structure holds information required for programming the CPU clock for
83
90
* various clock speeds.
@@ -91,6 +98,9 @@ struct exynos_cpuclk {
91
98
const unsigned long num_cfgs ;
92
99
struct notifier_block clk_nb ;
93
100
unsigned long flags ;
101
+
102
+ exynos_rate_change_fn_t pre_rate_cb ;
103
+ exynos_rate_change_fn_t post_rate_cb ;
94
104
};
95
105
96
106
/*
@@ -178,9 +188,10 @@ static void exynos_set_safe_div(void __iomem *base, unsigned long div,
178
188
179
189
/* handler for pre-rate change notification from parent clock */
180
190
static int exynos_cpuclk_pre_rate_change (struct clk_notifier_data * ndata ,
181
- struct exynos_cpuclk * cpuclk , void __iomem * base )
191
+ struct exynos_cpuclk * cpuclk )
182
192
{
183
193
const struct exynos_cpuclk_cfg_data * cfg_data = cpuclk -> cfg ;
194
+ void __iomem * base = cpuclk -> ctrl_base ;
184
195
unsigned long alt_prate = clk_hw_get_rate (cpuclk -> alt_parent );
185
196
unsigned long div0 , div1 = 0 , mux_reg ;
186
197
unsigned long flags ;
@@ -255,9 +266,10 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
255
266
256
267
/* handler for post-rate change notification from parent clock */
257
268
static int exynos_cpuclk_post_rate_change (struct clk_notifier_data * ndata ,
258
- struct exynos_cpuclk * cpuclk , void __iomem * base )
269
+ struct exynos_cpuclk * cpuclk )
259
270
{
260
271
const struct exynos_cpuclk_cfg_data * cfg_data = cpuclk -> cfg ;
272
+ void __iomem * base = cpuclk -> ctrl_base ;
261
273
unsigned long div = 0 , div_mask = DIV_MASK ;
262
274
unsigned long mux_reg ;
263
275
unsigned long flags ;
@@ -306,9 +318,10 @@ static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
306
318
307
319
/* handler for pre-rate change notification from parent clock */
308
320
static int exynos5433_cpuclk_pre_rate_change (struct clk_notifier_data * ndata ,
309
- struct exynos_cpuclk * cpuclk , void __iomem * base )
321
+ struct exynos_cpuclk * cpuclk )
310
322
{
311
323
const struct exynos_cpuclk_cfg_data * cfg_data = cpuclk -> cfg ;
324
+ void __iomem * base = cpuclk -> ctrl_base ;
312
325
unsigned long alt_prate = clk_hw_get_rate (cpuclk -> alt_parent );
313
326
unsigned long div0 , div1 = 0 , mux_reg ;
314
327
unsigned long flags ;
@@ -366,8 +379,9 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
366
379
367
380
/* handler for post-rate change notification from parent clock */
368
381
static int exynos5433_cpuclk_post_rate_change (struct clk_notifier_data * ndata ,
369
- struct exynos_cpuclk * cpuclk , void __iomem * base )
382
+ struct exynos_cpuclk * cpuclk )
370
383
{
384
+ void __iomem * base = cpuclk -> ctrl_base ;
371
385
unsigned long div = 0 , div_mask = DIV_MASK ;
372
386
unsigned long mux_reg ;
373
387
unsigned long flags ;
@@ -393,39 +407,14 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
393
407
{
394
408
struct clk_notifier_data * ndata = data ;
395
409
struct exynos_cpuclk * cpuclk ;
396
- void __iomem * base ;
397
410
int err = 0 ;
398
411
399
412
cpuclk = container_of (nb , struct exynos_cpuclk , clk_nb );
400
- base = cpuclk -> ctrl_base ;
401
413
402
414
if (event == PRE_RATE_CHANGE )
403
- err = exynos_cpuclk_pre_rate_change (ndata , cpuclk , base );
415
+ err = cpuclk -> pre_rate_cb (ndata , cpuclk );
404
416
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 );
429
418
430
419
return notifier_from_errno (err );
431
420
}
@@ -467,10 +456,14 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
467
456
cpuclk -> ctrl_base = ctx -> reg_base + clk_data -> offset ;
468
457
cpuclk -> lock = & ctx -> lock ;
469
458
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
+ }
474
467
475
468
ret = clk_notifier_register (parent -> clk , & cpuclk -> clk_nb );
476
469
if (ret ) {
0 commit comments