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