diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index e2e8f0c9f20a..e3bd28c9ef28 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -765,6 +765,9 @@ static void clk_disable_unused_subtree(struct clk_core *core) hlist_for_each_entry(child, &core->children, child_node) clk_disable_unused_subtree(child); + if (core->flags & CLK_OPS_PARENT_ENABLE) + clk_core_prepare_enable(core->parent); + flags = clk_enable_lock(); if (core->enable_count) @@ -789,6 +792,8 @@ static void clk_disable_unused_subtree(struct clk_core *core) unlock_out: clk_enable_unlock(flags); + if (core->flags & CLK_OPS_PARENT_ENABLE) + clk_core_disable_unprepare(core->parent); } static bool clk_ignore_unused; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index eeb2e69ee727..a39c0c530778 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -33,6 +33,8 @@ #define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */ #define CLK_SET_RATE_UNGATE BIT(10) /* clock needs to run to set rate */ #define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ +/* parents need enable during gate/ungate, set rate and re-parent */ +#define CLK_OPS_PARENT_ENABLE BIT(12) struct clk; struct clk_hw;