summaryrefslogtreecommitdiffstats
path: root/drivers/clk/qcom/gdsc.c
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@codeaurora.org>2015-12-01 21:42:13 +0530
committerStephen Boyd <sboyd@codeaurora.org>2016-02-11 16:24:53 -0800
commita823bb9fbefbac8d8bf37d5b4879ee876f2356c5 (patch)
tree500a14ca99fd063c1b270ee6e7c53dc27a29e033 /drivers/clk/qcom/gdsc.c
parent77b1067a19b4986b009f3279cc6b8ad1d29ff51c (diff)
downloadlinux-a823bb9fbefbac8d8bf37d5b4879ee876f2356c5.tar.bz2
clk: qcom: gdsc: Add support for votable gdscs
Some gdscs might be controlled via voting registers and might not really disable when the kernel intends to disable them (due to other votes keeping them enabled) Mark these gdscs with a flag for we do not check/wait on a disable status for these gdscs within the kernel disable callback. Also at boot, if these GDSCs are found to be ON, we make sure we vote for them before we inform the genpd framework about their status. If genpd gets no users, it then disables (removes the vote) them as part of genpd_poweroff_unused() Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk/qcom/gdsc.c')
-rw-r--r--drivers/clk/qcom/gdsc.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 9f530b73bd3e..f12d7b2bddd7 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -66,6 +66,17 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
if (ret)
return ret;
+ /* If disabling votable gdscs, don't poll on status */
+ if ((sc->flags & VOTABLE) && !en) {
+ /*
+ * Add a short delay here to ensure that an enable
+ * right after it was disabled does not put it in an
+ * unknown state
+ */
+ udelay(TIMEOUT_US);
+ return 0;
+ }
+
if (sc->gds_hw_ctrl) {
status_reg = sc->gds_hw_ctrl;
/*
@@ -199,6 +210,13 @@ static int gdsc_init(struct gdsc *sc)
if (on < 0)
return on;
+ /*
+ * Votable GDSCs can be ON due to Vote from other masters.
+ * If a Votable GDSC is ON, make sure we have a Vote.
+ */
+ if ((sc->flags & VOTABLE) && on)
+ gdsc_enable(&sc->pd);
+
if (on || (sc->pwrsts & PWRSTS_RET))
gdsc_force_mem_on(sc);
else