clk: samsung: Register clk provider only after registering its all clocks
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Wed, 18 Jun 2014 15:46:52 +0000 (17:46 +0200)
committerTomasz Figa <t.figa@samsung.com>
Mon, 30 Jun 2014 13:07:55 +0000 (15:07 +0200)
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>
13 files changed:
drivers/clk/samsung/clk-exynos3250.c
drivers/clk/samsung/clk-exynos4.c
drivers/clk/samsung/clk-exynos5250.c
drivers/clk/samsung/clk-exynos5260.c
drivers/clk/samsung/clk-exynos5410.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-exynos5440.c
drivers/clk/samsung/clk-s3c2410.c
drivers/clk/samsung/clk-s3c2412.c
drivers/clk/samsung/clk-s3c2443.c
drivers/clk/samsung/clk-s3c64xx.c
drivers/clk/samsung/clk.c
drivers/clk/samsung/clk.h

index 7a17bd4..9a43cc3 100644 (file)
@@ -776,5 +776,7 @@ static void __init exynos3250_cmu_init(struct device_node *np)
        samsung_clk_register_gate(ctx, gate_clks, ARRAY_SIZE(gate_clks));
 
        exynos3250_clk_sleep_init();
+
+       samsung_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init);
index 7f4a473..b08d310 100644 (file)
@@ -1252,6 +1252,8 @@ static void __init exynos4_clk_init(struct device_node *np,
 
        exynos4_clk_sleep_init();
 
+       samsung_clk_of_add_provider(np, ctx);
+
        pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
                "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
                exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
index 184f642..5861183 100644 (file)
@@ -820,6 +820,8 @@ static void __init exynos5250_clk_init(struct device_node *np)
 
        exynos5250_clk_sleep_init();
 
+       samsung_clk_of_add_provider(np, ctx);
+
        pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
                        _get_rate("div_arm2"));
 }
index 64596ba..ce3de97 100644 (file)
@@ -206,6 +206,8 @@ void __init exynos5260_cmu_register_one(struct device_node *np,
        if (cmu->clk_regs)
                exynos5260_clk_sleep_init(reg_base, cmu->clk_regs,
                        cmu->nr_clk_regs);
+
+       samsung_clk_of_add_provider(np, ctx);
 }
 
 
index c9505ab..231475b 100644 (file)
@@ -204,6 +204,8 @@ static void __init exynos5410_clk_init(struct device_node *np)
        samsung_clk_register_gate(ctx, exynos5410_gate_clks,
                        ARRAY_SIZE(exynos5410_gate_clks));
 
+       samsung_clk_of_add_provider(np, ctx);
+
        pr_debug("Exynos5410: clock setup completed.\n");
 }
 CLK_OF_DECLARE(exynos5410_clk, "samsung,exynos5410-clock", exynos5410_clk_init);
index 61eccf0..94e4360 100644 (file)
@@ -1251,6 +1251,8 @@ static void __init exynos5x_clk_init(struct device_node *np,
        }
 
        exynos5420_clk_sleep_init();
+
+       samsung_clk_of_add_provider(np, ctx);
 }
 
 static void __init exynos5420_clk_init(struct device_node *np)
index 647f144..2f182f2 100644 (file)
@@ -123,6 +123,8 @@ static void __init exynos5440_clk_init(struct device_node *np)
        samsung_clk_register_gate(ctx, exynos5440_gate_clks,
                        ARRAY_SIZE(exynos5440_gate_clks));
 
+       samsung_clk_of_add_provider(np, ctx);
+
        pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk"));
        pr_info("exynos5440 clock initialization complete\n");
 }
index 140f473..5d2f034 100644 (file)
@@ -466,6 +466,8 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
        }
 
        s3c2410_clk_sleep_init();
+
+       samsung_clk_of_add_provider(np, ctx);
 }
 
 static void __init s3c2410_clk_init(struct device_node *np)
index 23e4313..34af09f 100644 (file)
@@ -265,6 +265,8 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
                                   ARRAY_SIZE(s3c2412_aliases));
 
        s3c2412_clk_sleep_init();
+
+       samsung_clk_of_add_provider(np, ctx);
 }
 
 static void __init s3c2412_clk_init(struct device_node *np)
index c4bbdab..c92f853 100644 (file)
@@ -445,6 +445,8 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
        }
 
        s3c2443_clk_sleep_init();
+
+       samsung_clk_of_add_provider(np, ctx);
 }
 
 static void __init s3c2416_clk_init(struct device_node *np)
index 8889ff1..0f590e5 100644 (file)
@@ -518,6 +518,8 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
                                        ARRAY_SIZE(s3c64xx_clock_aliases));
        s3c64xx_clk_sleep_init();
 
+       samsung_clk_of_add_provider(np, ctx);
+
        pr_info("%s clocks: apll = %lu, mpll = %lu\n"
                "\tepll = %lu, arm_clk = %lu\n",
                is_s3c6400 ? "S3C6400" : "S3C6410",
index 49629c7..98fb31b 100644 (file)
@@ -53,7 +53,6 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
 {
        struct samsung_clk_provider *ctx;
        struct clk **clk_table;
-       int ret;
        int i;
 
        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,
        ctx->clk_data.clk_num = nr_clks;
        spin_lock_init(&ctx->lock);
 
-       if (!np)
-               return ctx;
-
-       ret = of_clk_add_provider(np, of_clk_src_onecell_get,
-                       &ctx->clk_data);
-       if (ret)
-               panic("could not register clock provide\n");
-
        return ctx;
 }
 
+void __init samsung_clk_of_add_provider(struct device_node *np,
+                               struct samsung_clk_provider *ctx)
+{
+       if (np) {
+               if (of_clk_add_provider(np, of_clk_src_onecell_get,
+                                       &ctx->clk_data))
+                       panic("could not register clk provider\n");
+       }
+}
+
 /* add a clock instance to the clock lookup table used for dt based lookup */
 void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk,
                                unsigned int id)
index 9693b80..92131f9 100644 (file)
@@ -327,6 +327,8 @@ struct samsung_pll_clock {
 extern struct samsung_clk_provider *__init samsung_clk_init(
                        struct device_node *np, void __iomem *base,
                        unsigned long nr_clks);
+extern void __init samsung_clk_of_add_provider(struct device_node *np,
+                       struct samsung_clk_provider *ctx);
 extern void __init samsung_clk_of_register_fixed_ext(
                        struct samsung_clk_provider *ctx,
                        struct samsung_fixed_rate_clock *fixed_rate_clk,