msm: clock-voter: Support default rate votes using the handoff feature
For some system clocks, it is necessary to enforce default rate votes
that persist until all drivers that will control these clocks have
initialized and made their initial requests.
Take, for example, a memory clock and the following sequence of events
that could occur during boot:
1) Bootloaders set the memory clock to 400MHz.
2) Driver A requires only 27MHz and asserts that as its vote. Since
this is the only vote, memory slows to 27MHz and system performance
slows to a crawl.
3) Driver A finishes its operation and decreases its vote to 0MHz.
Since it was the only voter, the memory clock turns off and the
system crashes.
All of this happens before Driver B, which is responsible for setting
the memory performance floor, has had a chance to initialize and assert
its own vote to keep the clock on at a decent rate.
In this simple example, the problem could be fixed by initializing
Driver B before Driver A, but such re-orderings are not always possible
due to boot dependencies.
The solution presented by this change is to allow default votes to be
associated with voter clocks. These will be asserted during clock
driver initialization using the handoff mechanism, and de-asserted
as part of the lateinit handoff mechanism or when a driver enables
the voter clock, whichever comes first.
Change-Id: I8de85d436ba18d7fe8088a7a489532e28de435a2
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index 8ff4878..177af8c 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -147,6 +147,15 @@
return true;
}
+enum handoff voter_clk_handoff(struct clk *clk)
+{
+ /* Apply default rate vote */
+ if (clk->rate)
+ return HANDOFF_ENABLED_CLK;
+
+ return HANDOFF_DISABLED_CLK;
+}
+
struct clk_ops clk_ops_voter = {
.enable = voter_clk_enable,
.disable = voter_clk_disable,