Some clocks are already enabled in HW even before the kernel
starts to boot. So, in order to make sure that these clocks do not
get disabled when clk_disable_unused call is done or when
reparenting clocks, we enable them in core on clock registration.
Such a clock will have to be registered with CLK_IGNORE_UNUSED flag
and also needs to have the is_enabled ops implemented.

Signed-off-by: Abel Vesa <abel.v...@nxp.com>
---
 drivers/clk/clk.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 3d751ae5bc70..26d55851cfa5 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3416,6 +3416,7 @@ static int __clk_core_init(struct clk_core *core)
        int ret;
        struct clk_core *parent;
        unsigned long rate;
+       bool is_hw_enabled = false;
        int phase;
 
        if (!core)
@@ -3558,12 +3559,20 @@ static int __clk_core_init(struct clk_core *core)
                rate = 0;
        core->rate = core->req_rate = rate;
 
+       /*
+        * If the clock has the CLK_IGNORE_UNUSED flag set and it is already
+        * enabled in HW, enable it in core too so it won't get accidentally
+        * disabled when walking the orphan tree and reparenting clocks
+        */
+       if (core->flags & CLK_IGNORE_UNUSED && core->ops->is_enabled)
+               is_hw_enabled = clk_core_is_enabled(core);
+
        /*
         * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
         * don't get accidentally disabled when walking the orphan tree and
         * reparenting clocks
         */
-       if (core->flags & CLK_IS_CRITICAL) {
+       if (core->flags & CLK_IS_CRITICAL || is_hw_enabled) {
                unsigned long flags;
 
                ret = clk_core_prepare(core);
-- 
2.29.2

Reply via email to