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 7a17bd40d1ddbe75dc1fac58e61b69306a16647f..9a43cc3e740152af18077f1058d2afafd861fc2d 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 7f4a473a7ad7c5dc44153f155baaeaafdfadf47b..b08d310bd1bd8b96aaf0a8ddf954de38b806498d 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 184f64293b26aa4c9f7ab0fef7a0a64e01ed4be2..5861183d12267b9e7bca8a87cd3f5d31231d4dad 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 64596ba58df19ff585aded59d34563728b192ec3..ce3de97e5f11299fd1d852f8ec4f1d6612cbf571 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 c9505ab9ee7063af0467ac276544b2484fe78868..231475bc2b99604ef16351ba49a3874c61d974b3 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 61eccf0dd72f1886c49d0624581699d44d1bb29f..94e43608bc86a4c8888ebc8889adfd63dd8f47f6 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 647f1440aa6a63802b4cc57d0a1acb74ae544981..2f182f2399ba59b755b9209e06ee28245c679190 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 140f4733c02e96e32826c58bf8c75c3ce805977a..5d2f03461bc5d2fe6cf4acd6ef11b379ef25e0bd 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 23e4313f625e5b19e088d17afd8cb52f64b22594..34af09f6a155745dc16ab2bcae4f008552a2753e 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 c4bbdabebaa4c9fd483c9ca8c98519a573e257c6..c92f853fca9f7ce76f562e76d912aae6004313cb 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 8889ff1c10fc401ab703505c45f569868b614e10..0f590e5550cb237ed1e73c836205ef501d723a78 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 49629c71c9e7769e98e473f784605e877bbf51de..98fb31bf569844f33e8800d82453d86b91d0f180 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 9693b80d924f27de6b375e5abcb03d86089f54e3..92131f972917e5205e9da116fce20eed8777be88 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,