clk: samsung: Use clk_hw API for calling clk framework from clk notifiers
authorMarek Szyprowski <m.szyprowski@samsung.com>
Tue, 2 Oct 2018 11:52:10 +0000 (13:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 24 Nov 2019 07:23:11 +0000 (08:23 +0100)
[ Upstream commit 1da220e3a5d22fccda0bc8542997abc1d1741268 ]

clk_notifier_register() documentation states, that the provided notifier
callbacks associated with the notifier must not re-enter into the clk
framework by calling any top-level clk APIs. Fix this by replacing
clk_get_rate() calls with clk_hw_get_rate(), which is safe in this
context.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Sylwester Nawrocki <snawrocki@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/clk/samsung/clk-cpu.c
drivers/clk/samsung/clk-cpu.h

index 6686e8ba61f9f768681810b4ceaa3afcb5ff43b6..82f023f29a61ffa1bf908f43cde1cea23e808cd7 100644 (file)
@@ -152,7 +152,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
                        struct exynos_cpuclk *cpuclk, void __iomem *base)
 {
        const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-       unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
+       unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
        unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
        unsigned long div0, div1 = 0, mux_reg;
        unsigned long flags;
@@ -280,7 +280,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
                        struct exynos_cpuclk *cpuclk, void __iomem *base)
 {
        const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-       unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
+       unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
        unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
        unsigned long div0, div1 = 0, mux_reg;
        unsigned long flags;
@@ -432,7 +432,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
        else
                cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
 
-       cpuclk->alt_parent = __clk_lookup(alt_parent);
+       cpuclk->alt_parent = __clk_get_hw(__clk_lookup(alt_parent));
        if (!cpuclk->alt_parent) {
                pr_err("%s: could not lookup alternate parent %s\n",
                                __func__, alt_parent);
index d4b6b517fe1b44689df28853cf894baa3799153d..bd38c6aa389706c92261cd72f4f0c8fd8906ba67 100644 (file)
@@ -49,7 +49,7 @@ struct exynos_cpuclk_cfg_data {
  */
 struct exynos_cpuclk {
        struct clk_hw                           hw;
-       struct clk                              *alt_parent;
+       struct clk_hw                           *alt_parent;
        void __iomem                            *ctrl_base;
        spinlock_t                              *lock;
        const struct exynos_cpuclk_cfg_data     *cfg;