msm: clock: Move voltage scaling to prepare/unprepare

Move the voltage calls to a sleepable context so we can avoid
spinning for hundreds of microseconds with interrupts disabled
waiting for a regulator to increase. This change also paves the
way to making the clock driver into a real regulator consumer
that uses the proper regulator APIs instead of the MSM specific
rpm_vreg API.

Doing this also requires us to make clk_set_rate() a sleeping
call so that concurrent clk_prepare() and clk_set_rate() calls
are synchronized. Making clk_set_rate() sleepable also
necessitates moving the clk_set_rate() call in clock-voter.c to a
sleepable context. Do that by having clock-voter aggregate and
update the rate in prepare/unprepare instead of enable/disable
(note that enable/disable of voter clocks implicitly calls
enable/disable on the parent via generic clock code).

Now that clk_set_rate() is sleeping, call clk_prepare() and
clk_unprepare() in the clock-local code when a rate change
requires reparenting the clock. This cleans up a problem we have
where sources may be left unprepared by a clock rate switch
(hence the default true warned flag for PLLs and crystals).

Change-Id: I493a00261055001a68fa884daa52e3d281ec6a2d
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 373cf47..2ec4e38 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -2883,6 +2883,7 @@
 };
 
 struct pix_rdi_clk {
+	bool prepared;
 	bool enabled;
 	unsigned long cur_rate;
 
@@ -2908,6 +2909,7 @@
 	unsigned long flags;
 	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
 	struct clk **mux_map = pix_rdi_mux_map;
+	unsigned long old_rate = rdi->cur_rate;
 
 	/*
 	 * These clocks select three inputs via two muxes. One mux selects
@@ -2918,7 +2920,7 @@
 	 * needs to be on at what time.
 	 */
 	for (i = 0; mux_map[i]; i++) {
-		ret = clk_enable(mux_map[i]);
+		ret = clk_prepare_enable(mux_map[i]);
 		if (ret)
 			goto err;
 	}
@@ -2927,11 +2929,21 @@
 		goto err;
 	}
 	/* Keep the new source on when switching inputs of an enabled clock */
-	if (rdi->enabled) {
-		clk_disable(mux_map[rdi->cur_rate]);
-		clk_enable(mux_map[rate]);
+	if (rdi->prepared) {
+		ret = clk_prepare(mux_map[rate]);
+		if (ret)
+			goto err;
 	}
-	spin_lock_irqsave(&local_clock_reg_lock, flags);
+	spin_lock_irqsave(&c->lock, flags);
+	if (rdi->enabled) {
+		ret = clk_enable(mux_map[rate]);
+		if (ret) {
+			spin_unlock_irqrestore(&c->lock, flags);
+			clk_unprepare(mux_map[rate]);
+			goto err;
+		}
+	}
+	spin_lock(&local_clock_reg_lock);
 	reg = readl_relaxed(rdi->s2_reg);
 	reg &= ~rdi->s2_mask;
 	reg |= rate == 2 ? rdi->s2_mask : 0;
@@ -2953,10 +2965,16 @@
 	mb();
 	udelay(1);
 	rdi->cur_rate = rate;
-	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+	spin_unlock(&local_clock_reg_lock);
+
+	if (rdi->enabled)
+		clk_disable(mux_map[old_rate]);
+	spin_unlock_irqrestore(&c->lock, flags);
+	if (rdi->prepared)
+		clk_unprepare(mux_map[old_rate]);
 err:
 	for (i--; i >= 0; i--)
-		clk_disable(mux_map[i]);
+		clk_disable_unprepare(mux_map[i]);
 
 	return 0;
 }
@@ -2966,6 +2984,13 @@
 	return to_pix_rdi_clk(c)->cur_rate;
 }
 
+static int pix_rdi_clk_prepare(struct clk *c)
+{
+	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
+	rdi->prepared = true;
+	return 0;
+}
+
 static int pix_rdi_clk_enable(struct clk *c)
 {
 	unsigned long flags;
@@ -2990,6 +3015,12 @@
 	rdi->enabled = false;
 }
 
+static void pix_rdi_clk_unprepare(struct clk *c)
+{
+	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
+	rdi->prepared = false;
+}
+
 static int pix_rdi_clk_reset(struct clk *c, enum clk_reset_action action)
 {
 	return branch_reset(&to_pix_rdi_clk(c)->b, action);
@@ -3026,8 +3057,10 @@
 }
 
 static struct clk_ops clk_ops_pix_rdi_8960 = {
+	.prepare = pix_rdi_clk_prepare,
 	.enable = pix_rdi_clk_enable,
 	.disable = pix_rdi_clk_disable,
+	.unprepare = pix_rdi_clk_unprepare,
 	.handoff = pix_rdi_clk_handoff,
 	.set_rate = pix_rdi_clk_set_rate,
 	.get_rate = pix_rdi_clk_get_rate,