msm: pm: Disable cpu clk during retention

The CPU clock source MUXes cannot switch while a CPU is in
retention, but callers of acpuclock APIs may not known that
the CPU is in retention.

Fix issue by disabling the cpu clk before entering retention and
re-enable them on exit. This would temporarily switch the CPU to 300Mhz
and clk api would buffer any clock requests until the clk is enabled
when the core comes out of retention.

CRs-fixed: 535967
Change-Id: I103e41fc8ef78cd412b7860bf525ea9cd99ff283
Signed-off-by: Mahesh Sivasubramanian <msivasub@codeaurora.org>
Signed-off-by: Anil kumar mamidala <amami@codeaurora.org>
diff --git a/arch/arm/mach-msm/msm-pm.c b/arch/arm/mach-msm/msm-pm.c
index 5f8657e..fab86d3 100644
--- a/arch/arm/mach-msm/msm-pm.c
+++ b/arch/arm/mach-msm/msm-pm.c
@@ -403,6 +403,8 @@
 {
 	int ret = 0;
 	int cpu = smp_processor_id();
+	int saved_rate = 0;
+	struct clk *cpu_clk = per_cpu(cpu_clks, cpu);
 
 	spin_lock(&retention_lock);
 
@@ -412,10 +414,25 @@
 	cpumask_set_cpu(cpu, &retention_cpus);
 	spin_unlock(&retention_lock);
 
+	if (use_acpuclk_apis)
+		saved_rate = acpuclk_power_collapse();
+	else
+		clk_disable(cpu_clk);
+
 	ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_RETENTION, false);
 	WARN_ON(ret);
 
 	msm_arch_idle();
+
+	if (use_acpuclk_apis) {
+		if (acpuclk_set_rate(cpu, saved_rate, SETRATE_PC))
+			pr_err("%s(): Error setting acpuclk_set_rate\n",
+					__func__);
+	} else {
+		if (clk_enable(cpu_clk))
+			pr_err("%s(): Error restoring cpu clk\n", __func__);
+	}
+
 	spin_lock(&retention_lock);
 	cpumask_clear_cpu(cpu, &retention_cpus);
 bailout: