diff options
author | Saravana Kannan <saravanak@google.com> | 2019-12-06 11:17:26 -0800 |
---|---|---|
committer | Sumit Semwal <sumit.semwal@linaro.org> | 2021-01-27 23:55:01 +0530 |
commit | bf1b6adbf9a02f1d7d7c93ecf08eaa6584767d44 (patch) | |
tree | e4577c1867787b97d75b2a32555ce3e77b14cfba | |
parent | 0689cf44ba33258658f19613e5a394a0d19dabbc (diff) |
ANDROID: GKI: clk: Don't disable unused clocks with sync state support
Some clocks (that are left on at boot) of a clock provider with sync
state support might not have their "state held" during clock
registration because they remain orphans even after all the clocks in
the clock provider are registered.
These are typically clocks whose current parent is registered by a
different clock provider. When the other clock providers are registered,
these orphan clocks get adopted (no longer orphans) and will have their
"state held".
However if the clock provider of the parent clocks are modules, then
these orphan clocks would get turned off during late_initcall_sync()
because they'd look like unused clocks at that point. This might turn
off clocks that are in use by an active hardware block and cause system
issues.
To avoid this, don't turn off an unused clock if its clock provider has
sync state support and the clock doesn't have the CLK_DONT_HOLD_STATE
flag set.
Bug: 144066914
Signed-off-by: Saravana Kannan <saravanak@google.com>
Change-Id: I1f1dbca4994a5b7085930996e1cc5e848266436c
-rw-r--r-- | drivers/clk/clk.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 29b2831b9cd0..8d49176311ad 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1196,6 +1196,10 @@ static void __init clk_unprepare_unused_subtree(struct clk_core *core) hlist_for_each_entry(child, &core->children, child_node) clk_unprepare_unused_subtree(child); + if (dev_has_sync_state(core->dev) && + !(core->flags & CLK_DONT_HOLD_STATE)) + return; + if (core->prepare_count) return; @@ -1227,6 +1231,10 @@ static void __init clk_disable_unused_subtree(struct clk_core *core) hlist_for_each_entry(child, &core->children, child_node) clk_disable_unused_subtree(child); + if (dev_has_sync_state(core->dev) && + !(core->flags & CLK_DONT_HOLD_STATE)) + return; + if (core->flags & CLK_OPS_PARENT_ENABLE) clk_core_prepare_enable(core->parent); |