diff options
-rw-r--r-- | drivers/clk/clk.c | 18 | ||||
-rw-r--r-- | include/linux/clk-provider.h | 1 |
2 files changed, 19 insertions, 0 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index f13c3f4228d4..bd64a9414de2 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1443,6 +1443,15 @@ static void clk_change_rate(struct clk_core *core) else if (core->parent) best_parent_rate = core->parent->rate; + if (core->flags & CLK_SET_RATE_UNGATE) { + unsigned long flags; + + clk_core_prepare(core); + flags = clk_enable_lock(); + clk_core_enable(core); + clk_enable_unlock(flags); + } + if (core->new_parent && core->new_parent != core->parent) { old_parent = __clk_set_parent_before(core, core->new_parent); trace_clk_set_parent(core, core->new_parent); @@ -1469,6 +1478,15 @@ static void clk_change_rate(struct clk_core *core) core->rate = clk_recalc(core, best_parent_rate); + if (core->flags & CLK_SET_RATE_UNGATE) { + unsigned long flags; + + flags = clk_enable_lock(); + clk_core_disable(core); + clk_enable_unlock(flags); + clk_core_unprepare(core); + } + if (core->notifier_count && old_rate != core->rate) __clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate); diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c56988ac63f7..a971ce462565 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -31,6 +31,7 @@ #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ #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 */ struct clk; struct clk_hw; |