aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2014-06-18 11:46:52 -0400
committerTomasz Figa <t.figa@samsung.com>2014-06-30 09:07:55 -0400
commitd5e136a21b2028fb1f45143ea7112d5869bfc6c7 (patch)
tree5515a38250e241056cf3538bbbf6deec37812765
parentbdfcdf18c380a3c376b42709a89eb2cc52e95ae0 (diff)
clk: samsung: Register clk provider only after registering its all clocks
Ensure the clock provider is not registered until after all its related clocks were created and are ready to use. Currently there are races possible and any (of_)clk_get() call right after a clock provider's clk_init_cb callback call may fail. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
-rw-r--r--drivers/clk/samsung/clk-exynos3250.c2
-rw-r--r--drivers/clk/samsung/clk-exynos4.c2
-rw-r--r--drivers/clk/samsung/clk-exynos5250.c2
-rw-r--r--drivers/clk/samsung/clk-exynos5260.c2
-rw-r--r--drivers/clk/samsung/clk-exynos5410.c2
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c2
-rw-r--r--drivers/clk/samsung/clk-exynos5440.c2
-rw-r--r--drivers/clk/samsung/clk-s3c2410.c2
-rw-r--r--drivers/clk/samsung/clk-s3c2412.c2
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c2
-rw-r--r--drivers/clk/samsung/clk-s3c64xx.c2
-rw-r--r--drivers/clk/samsung/clk.c19
-rw-r--r--drivers/clk/samsung/clk.h2
13 files changed, 34 insertions, 9 deletions
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index 7a17bd40d1dd..9a43cc3e7401 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -776,5 +776,7 @@ static void __init exynos3250_cmu_init(struct device_node *np)
776 samsung_clk_register_gate(ctx, gate_clks, ARRAY_SIZE(gate_clks)); 776 samsung_clk_register_gate(ctx, gate_clks, ARRAY_SIZE(gate_clks));
777 777
778 exynos3250_clk_sleep_init(); 778 exynos3250_clk_sleep_init();
779
780 samsung_clk_of_add_provider(np, ctx);
779} 781}
780CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init); 782CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init);
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 7f4a473a7ad7..b08d310bd1bd 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1252,6 +1252,8 @@ static void __init exynos4_clk_init(struct device_node *np,
1252 1252
1253 exynos4_clk_sleep_init(); 1253 exynos4_clk_sleep_init();
1254 1254
1255 samsung_clk_of_add_provider(np, ctx);
1256
1255 pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" 1257 pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
1256 "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", 1258 "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
1257 exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", 1259 exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 184f64293b26..5861183d1226 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -820,6 +820,8 @@ static void __init exynos5250_clk_init(struct device_node *np)
820 820
821 exynos5250_clk_sleep_init(); 821 exynos5250_clk_sleep_init();
822 822
823 samsung_clk_of_add_provider(np, ctx);
824
823 pr_info("Exynos5250: clock setup completed, armclk=%ld\n", 825 pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
824 _get_rate("div_arm2")); 826 _get_rate("div_arm2"));
825} 827}
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index 64596ba58df1..ce3de97e5f11 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -206,6 +206,8 @@ void __init exynos5260_cmu_register_one(struct device_node *np,
206 if (cmu->clk_regs) 206 if (cmu->clk_regs)
207 exynos5260_clk_sleep_init(reg_base, cmu->clk_regs, 207 exynos5260_clk_sleep_init(reg_base, cmu->clk_regs,
208 cmu->nr_clk_regs); 208 cmu->nr_clk_regs);
209
210 samsung_clk_of_add_provider(np, ctx);
209} 211}
210 212
211 213
diff --git a/drivers/clk/samsung/clk-exynos5410.c b/drivers/clk/samsung/clk-exynos5410.c
index c9505ab9ee70..231475bc2b99 100644
--- a/drivers/clk/samsung/clk-exynos5410.c
+++ b/drivers/clk/samsung/clk-exynos5410.c
@@ -204,6 +204,8 @@ static void __init exynos5410_clk_init(struct device_node *np)
204 samsung_clk_register_gate(ctx, exynos5410_gate_clks, 204 samsung_clk_register_gate(ctx, exynos5410_gate_clks,
205 ARRAY_SIZE(exynos5410_gate_clks)); 205 ARRAY_SIZE(exynos5410_gate_clks));
206 206
207 samsung_clk_of_add_provider(np, ctx);
208
207 pr_debug("Exynos5410: clock setup completed.\n"); 209 pr_debug("Exynos5410: clock setup completed.\n");
208} 210}
209CLK_OF_DECLARE(exynos5410_clk, "samsung,exynos5410-clock", exynos5410_clk_init); 211CLK_OF_DECLARE(exynos5410_clk, "samsung,exynos5410-clock", exynos5410_clk_init);
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 61eccf0dd72f..94e43608bc86 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -1251,6 +1251,8 @@ static void __init exynos5x_clk_init(struct device_node *np,
1251 } 1251 }
1252 1252
1253 exynos5420_clk_sleep_init(); 1253 exynos5420_clk_sleep_init();
1254
1255 samsung_clk_of_add_provider(np, ctx);
1254} 1256}
1255 1257
1256static void __init exynos5420_clk_init(struct device_node *np) 1258static void __init exynos5420_clk_init(struct device_node *np)
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c
index 647f1440aa6a..2f182f2399ba 100644
--- a/drivers/clk/samsung/clk-exynos5440.c
+++ b/drivers/clk/samsung/clk-exynos5440.c
@@ -123,6 +123,8 @@ static void __init exynos5440_clk_init(struct device_node *np)
123 samsung_clk_register_gate(ctx, exynos5440_gate_clks, 123 samsung_clk_register_gate(ctx, exynos5440_gate_clks,
124 ARRAY_SIZE(exynos5440_gate_clks)); 124 ARRAY_SIZE(exynos5440_gate_clks));
125 125
126 samsung_clk_of_add_provider(np, ctx);
127
126 pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk")); 128 pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk"));
127 pr_info("exynos5440 clock initialization complete\n"); 129 pr_info("exynos5440 clock initialization complete\n");
128} 130}
diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
index 140f4733c02e..5d2f03461bc5 100644
--- a/drivers/clk/samsung/clk-s3c2410.c
+++ b/drivers/clk/samsung/clk-s3c2410.c
@@ -466,6 +466,8 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
466 } 466 }
467 467
468 s3c2410_clk_sleep_init(); 468 s3c2410_clk_sleep_init();
469
470 samsung_clk_of_add_provider(np, ctx);
469} 471}
470 472
471static void __init s3c2410_clk_init(struct device_node *np) 473static void __init s3c2410_clk_init(struct device_node *np)
diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c
index 23e4313f625e..34af09f6a155 100644
--- a/drivers/clk/samsung/clk-s3c2412.c
+++ b/drivers/clk/samsung/clk-s3c2412.c
@@ -265,6 +265,8 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
265 ARRAY_SIZE(s3c2412_aliases)); 265 ARRAY_SIZE(s3c2412_aliases));
266 266
267 s3c2412_clk_sleep_init(); 267 s3c2412_clk_sleep_init();
268
269 samsung_clk_of_add_provider(np, ctx);
268} 270}
269 271
270static void __init s3c2412_clk_init(struct device_node *np) 272static void __init s3c2412_clk_init(struct device_node *np)
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
index c4bbdabebaa4..c92f853fca9f 100644
--- a/drivers/clk/samsung/clk-s3c2443.c
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -445,6 +445,8 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
445 } 445 }
446 446
447 s3c2443_clk_sleep_init(); 447 s3c2443_clk_sleep_init();
448
449 samsung_clk_of_add_provider(np, ctx);
448} 450}
449 451
450static void __init s3c2416_clk_init(struct device_node *np) 452static void __init s3c2416_clk_init(struct device_node *np)
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
index 8889ff1c10fc..0f590e5550cb 100644
--- a/drivers/clk/samsung/clk-s3c64xx.c
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -518,6 +518,8 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
518 ARRAY_SIZE(s3c64xx_clock_aliases)); 518 ARRAY_SIZE(s3c64xx_clock_aliases));
519 s3c64xx_clk_sleep_init(); 519 s3c64xx_clk_sleep_init();
520 520
521 samsung_clk_of_add_provider(np, ctx);
522
521 pr_info("%s clocks: apll = %lu, mpll = %lu\n" 523 pr_info("%s clocks: apll = %lu, mpll = %lu\n"
522 "\tepll = %lu, arm_clk = %lu\n", 524 "\tepll = %lu, arm_clk = %lu\n",
523 is_s3c6400 ? "S3C6400" : "S3C6410", 525 is_s3c6400 ? "S3C6400" : "S3C6410",
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index 49629c71c9e7..98fb31bf5698 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -53,7 +53,6 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
53{ 53{
54 struct samsung_clk_provider *ctx; 54 struct samsung_clk_provider *ctx;
55 struct clk **clk_table; 55 struct clk **clk_table;
56 int ret;
57 int i; 56 int i;
58 57
59 ctx = kzalloc(sizeof(struct samsung_clk_provider), GFP_KERNEL); 58 ctx = kzalloc(sizeof(struct samsung_clk_provider), GFP_KERNEL);
@@ -72,17 +71,19 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
72 ctx->clk_data.clk_num = nr_clks; 71 ctx->clk_data.clk_num = nr_clks;
73 spin_lock_init(&ctx->lock); 72 spin_lock_init(&ctx->lock);
74 73
75 if (!np)
76 return ctx;
77
78 ret = of_clk_add_provider(np, of_clk_src_onecell_get,
79 &ctx->clk_data);
80 if (ret)
81 panic("could not register clock provide\n");
82
83 return ctx; 74 return ctx;
84} 75}
85 76
77void __init samsung_clk_of_add_provider(struct device_node *np,
78 struct samsung_clk_provider *ctx)
79{
80 if (np) {
81 if (of_clk_add_provider(np, of_clk_src_onecell_get,
82 &ctx->clk_data))
83 panic("could not register clk provider\n");
84 }
85}
86
86/* add a clock instance to the clock lookup table used for dt based lookup */ 87/* add a clock instance to the clock lookup table used for dt based lookup */
87void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk, 88void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk,
88 unsigned int id) 89 unsigned int id)
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 9693b80d924f..92131f972917 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -327,6 +327,8 @@ struct samsung_pll_clock {
327extern struct samsung_clk_provider *__init samsung_clk_init( 327extern struct samsung_clk_provider *__init samsung_clk_init(
328 struct device_node *np, void __iomem *base, 328 struct device_node *np, void __iomem *base,
329 unsigned long nr_clks); 329 unsigned long nr_clks);
330extern void __init samsung_clk_of_add_provider(struct device_node *np,
331 struct samsung_clk_provider *ctx);
330extern void __init samsung_clk_of_register_fixed_ext( 332extern void __init samsung_clk_of_register_fixed_ext(
331 struct samsung_clk_provider *ctx, 333 struct samsung_clk_provider *ctx,
332 struct samsung_fixed_rate_clock *fixed_rate_clk, 334 struct samsung_fixed_rate_clock *fixed_rate_clk,