msm: restart: Add support for MSM8974

Refactor the existing restart code to split out the
download mode configuration into its own function, and add
support for restarting MSM8974 targets using the new
PS_HOLD register.

Change-Id: Ibe0677d1054769c94edec390d3e7b4e5dd877b79
Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 38f1d2b..7411e0b 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -249,6 +249,8 @@
 	select MSM_PIL
 	select MSM_SPM_V2
 	select MSM_L2_SPM
+	select MSM_NATIVE_RESTART
+	select MSM_RESTART_V2
 	select MSM_PM8X60 if PM
 	select MAY_HAVE_SPARSE_IRQ
 	select SPARSE_IRQ
@@ -381,6 +383,9 @@
 config  MSM_KRAIT_WFE_FIXUP
 	bool
 
+config  MSM_RESTART_V2
+	bool
+
 config  ARCH_MSM_CORTEX_A5
 	bool
 	select HAVE_HW_BRKPT_RESERVED_RW_ACCESS
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index b2a4ce2..8f9a0ef 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -23,6 +23,7 @@
 #include <asm/mach/time.h>
 #include <mach/socinfo.h>
 #include <mach/board.h>
+#include <mach/restart.h>
 
 static void __init msm_dt_timer_init(void)
 {
@@ -87,4 +88,5 @@
 	.dt_compat = msm_dt_match,
 	.reserve = msm_dt_reserve,
 	.init_very_early = msm_dt_init_very_early,
+	.restart = msm_restart,
 MACHINE_END
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 7288c1d..519dbb3 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -47,6 +47,12 @@
 
 #define SCM_IO_DISABLE_PMIC_ARBITER	1
 
+#ifdef CONFIG_MSM_RESTART_V2
+#define use_restart_v2()	1
+#else
+#define use_restart_v2()	0
+#endif
+
 static int restart_mode;
 void *restart_reason;
 
@@ -177,9 +183,8 @@
 	return IRQ_HANDLED;
 }
 
-void msm_restart(char mode, const char *cmd)
+static void msm_restart_prepare(const char *cmd)
 {
-
 #ifdef CONFIG_MSM_DLOAD_MODE
 
 	/* This looks like a normal reboot at this point. */
@@ -197,8 +202,6 @@
 		set_dload_mode(0);
 #endif
 
-	printk(KERN_NOTICE "Going down for restart now\n");
-
 	pm8xxx_reset_pwr_off(1);
 
 	if (cmd != NULL) {
@@ -214,19 +217,30 @@
 			__raw_writel(0x77665501, restart_reason);
 		}
 	}
+}
 
-	__raw_writel(0, msm_tmr0_base + WDT0_EN);
-	if (!(machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())) {
-		mb();
-		__raw_writel(0, PSHOLD_CTL_SU); /* Actually reset the chip */
-		mdelay(5000);
-		pr_notice("PS_HOLD didn't work, falling back to watchdog\n");
-	}
+void msm_restart(char mode, const char *cmd)
+{
+	printk(KERN_NOTICE "Going down for restart now\n");
 
-	__raw_writel(1, msm_tmr0_base + WDT0_RST);
-	__raw_writel(5*0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
-	__raw_writel(0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
-	__raw_writel(1, msm_tmr0_base + WDT0_EN);
+	if (!use_restart_v2()) {
+		msm_restart_prepare(cmd);
+		__raw_writel(0, msm_tmr0_base + WDT0_EN);
+		if (!(machine_is_msm8x60_fusion() ||
+		      machine_is_msm8x60_fusn_ffa())) {
+			mb();
+			 /* Actually reset the chip */
+			__raw_writel(0, PSHOLD_CTL_SU);
+			mdelay(5000);
+			pr_notice("PS_HOLD didn't work, falling back to watchdog\n");
+		}
+
+		__raw_writel(1, msm_tmr0_base + WDT0_RST);
+		__raw_writel(5*0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
+		__raw_writel(0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
+		__raw_writel(1, msm_tmr0_base + WDT0_EN);
+	} else
+		__raw_writel(0, MSM_MPM2_PSHOLD_BASE);
 
 	mdelay(10000);
 	printk(KERN_ERR "Restarting has failed\n");