msm: pm2: Handle modem early exit properly in PC for 8625

When the APPS decides to enter into power collapse(idle/suspend)
it executes the wfi instruction and generate A2M6_INT interrupt
to modem to remove the power rail. But there are cases where modem
receives an interrupt for the apps and uses M2A6_INT to wake up the
apps while the apps is trying to do a power collapse. But APPS has
executed the WFI instruction which causes SPM to put the core into
GDFS mode. Once APPS receives the M2A6_INT from modem it starts the
execution from the warm boot specficied by the core and return the
value as "1"(which tells PC is successful) even on modem early exit.

Currently this scenario is not properly handled for 8625 target and
these changes will differentiate between the modem early exit & full
power collapse.

Change-Id: I3b2bd37184b894a89197bc2097d671d2177ad437
Signed-off-by: Murali Nalajala <mnalajal@codeaurora.org>
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index a5e52be..4f3c7e4 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -565,7 +565,7 @@
 		__raw_writel(0, APPS_CLK_SLEEP_EN);
 		mb();
 
-		if (cpu_is_msm8625()) {
+		if (cpu_is_msm8625() && power_collapsed) {
 			/*
 			 * enable the SCU while coming out of power
 			 * collapse.
@@ -1089,6 +1089,8 @@
 	unsigned long saved_acpuclk_rate;
 	int collapsed = 0;
 	int ret;
+	int val;
+	int modem_early_exit = 0;
 
 	MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
 		KERN_INFO, "%s(): idle %d, delay %u, limit %u\n", __func__,
@@ -1194,8 +1196,25 @@
 #endif
 
 	collapsed = msm_pm_collapse();
-	if (collapsed)
-		power_collapsed = 1;
+
+	/*
+	 * TBD: Currently recognise the MODEM early exit
+	 * path by reading the MPA5_GDFS_CNT_VAL register.
+	 */
+	if (cpu_is_msm8625()) {
+		/*
+		 * on system reset default value of MPA5_GDFS_CNT_VAL
+		 * is = 0xFF, later power driver reprogrammed this
+		 * as: 0x000300FF. Currently based on the value of
+		 * MPA5_GDFS_CNT_VAL register decide whether it is
+		 * a modem early exit are not.
+		 */
+		val = __raw_readl(MSM_CFG_CTL_BASE + 0x38);
+		if (val != 0xFF)
+			modem_early_exit = 1;
+		else
+			power_collapsed = 1;
+	}
 
 #ifdef CONFIG_CACHE_L2X0
 	l2x0_resume(collapsed);
@@ -1256,7 +1275,7 @@
 	}
 
 	/* Sanity check */
-	if (collapsed) {
+	if (collapsed && !modem_early_exit) {
 		BUG_ON(!(state_grps[0].value_read & DEM_MASTER_SMSM_RSA));
 	} else {
 		BUG_ON(!(state_grps[0].value_read &