From: Gabriel Fernandez <gabriel.fernan...@foss.st.com>

In RCC the ops of the CCF registered CLK device can be called directly,
this patch avoid recursive call of clk_ function done by CCF clock
framework which update the clock information, for example
clk_enable is called 2 times, clkp->enable_count is increased 2 times.

Signed-off-by: Gabriel Fernandez <gabriel.fernan...@foss.st.com>
Signed-off-by: Patrice Chotard <patrice.chot...@foss.st.com>
Cc: Lukasz Majewski <lu...@denx.de>
Cc: Sean Anderson <sean...@gmail.com>
---

 drivers/clk/stm32/clk-stm32-core.c | 68 ++++++++++++++++++++++++++++--
 1 file changed, 64 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/stm32/clk-stm32-core.c 
b/drivers/clk/stm32/clk-stm32-core.c
index df3b35b1003..a0ae89d0912 100644
--- a/drivers/clk/stm32/clk-stm32-core.c
+++ b/drivers/clk/stm32/clk-stm32-core.c
@@ -70,11 +70,71 @@ ulong clk_stm32_get_rate_by_name(const char *name)
        return 0;
 }
 
+static const struct clk_ops *clk_dev_ops(struct udevice *dev)
+{
+       return (const struct clk_ops *)dev->driver->ops;
+}
+
+static int stm32_clk_endisable(struct clk *clk, bool enable)
+{
+       const struct clk_ops *ops;
+       struct clk *c = NULL;
+
+       if (!clk->id || clk_get_by_id(clk->id, &c))
+               return -ENOENT;
+
+       ops = clk_dev_ops(c->dev);
+       if (!ops->enable || !ops->disable)
+               return 0;
+
+       return enable ? ops->enable(c) : ops->disable(c);
+}
+
+static int stm32_clk_enable(struct clk *clk)
+{
+       return stm32_clk_endisable(clk, true);
+}
+
+static int stm32_clk_disable(struct clk *clk)
+{
+       return stm32_clk_endisable(clk, false);
+}
+
+static ulong stm32_clk_get_rate(struct clk *clk)
+{
+       const struct clk_ops *ops;
+       struct clk *c = NULL;
+
+       if (!clk->id || clk_get_by_id(clk->id, &c))
+               return -ENOENT;
+
+       ops = clk_dev_ops(c->dev);
+       if (!ops->get_rate)
+               return -ENOSYS;
+
+       return ops->get_rate(c);
+}
+
+static ulong stm32_clk_set_rate(struct clk *clk, unsigned long clk_rate)
+{
+       const struct clk_ops *ops;
+       struct clk *c = NULL;
+
+       if (!clk->id || clk_get_by_id(clk->id, &c))
+               return -ENOENT;
+
+       ops = clk_dev_ops(c->dev);
+       if (!ops->set_rate)
+               return -ENOSYS;
+
+       return ops->set_rate(c, clk_rate);
+}
+
 const struct clk_ops stm32_clk_ops = {
-       .enable = ccf_clk_enable,
-       .disable = ccf_clk_disable,
-       .get_rate = ccf_clk_get_rate,
-       .set_rate = ccf_clk_set_rate,
+       .enable = stm32_clk_enable,
+       .disable = stm32_clk_disable,
+       .get_rate = stm32_clk_get_rate,
+       .set_rate = stm32_clk_set_rate,
 };
 
 #define RCC_MP_ENCLRR_OFFSET   4
-- 
2.25.1

Reply via email to