Merge "msm: restart_7k: Move restart code out of pm2.c" into msm-3.4
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 2346cf8..e21eed5 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -39,6 +39,7 @@
 	select MSM_RUN_QUEUE_STATS if MSM_SOC_REV_A
 	select DONT_MAP_HOLE_AFTER_MEMBANK0
 	select MIGHT_HAVE_CACHE_L2X0
+	select MSM_MODEM_RESTART
 
 config ARCH_MSM7X30
 	bool "MSM7x30"
@@ -65,6 +66,7 @@
 	select MULTI_IRQ_HANDLER
 	select MSM_PM2 if PM
 	select HOLES_IN_ZONE if SPARSEMEM
+	select MSM_MODEM_RESTART
 
 config ARCH_QSD8X50
 	bool "QSD8X50"
@@ -78,6 +80,7 @@
 	select MSM_GPIOMUX
 	select MSM_DALRPC
 	select MSM_PM2 if PM
+	select MSM_MODEM_RESTART
 
 config ARCH_MSM8X60
 	bool "MSM8X60"
@@ -2090,6 +2093,9 @@
 config MSM_NATIVE_RESTART
 	bool
 
+config MSM_MODEM_RESTART
+	bool
+
 config MSM_PM2
 	depends on PM
 	bool
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 841ed3c..f7f488a 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -363,6 +363,7 @@
 obj-$(CONFIG_MSM_FAKE_BATTERY) += fish_battery.o
 obj-$(CONFIG_MSM_RPC_VIBRATOR) += msm_vibrator.o
 obj-$(CONFIG_MSM_NATIVE_RESTART) += restart.o
+obj-$(CONFIG_MSM_MODEM_RESTART) += restart_7k.o
 
 obj-$(CONFIG_MSM_PROC_COMM_REGULATOR) += proccomm-regulator.o
 ifdef CONFIG_MSM_PROC_COMM_REGULATOR
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index 4184a86..8febe26 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -33,4 +33,5 @@
 void __init msm8x25_spm_device_init(void);
 void __init msm8x25_kgsl_3d0_init(void);
 void __iomem *core1_reset_base(void);
+extern void setup_mm_for_reboot(void);
 #endif
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 7a8e4c3..8fccda4 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -21,10 +21,8 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/pm.h>
 #include <linux/pm_qos.h>
 #include <linux/suspend.h>
-#include <linux/reboot.h>
 #include <linux/io.h>
 #include <linux/tick.h>
 #include <linux/memory.h>
@@ -34,7 +32,6 @@
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #endif
-#include <asm/system_misc.h>
 #ifdef CONFIG_CACHE_L2X0
 #include <asm/hardware/cache-l2x0.h>
 #endif
@@ -1577,55 +1574,6 @@
 	}
 }
 
-/******************************************************************************
- * Restart Definitions
- *****************************************************************************/
-
-static uint32_t restart_reason = 0x776655AA;
-
-static void msm_pm_power_off(void)
-{
-	msm_rpcrouter_close();
-	msm_proc_comm(PCOM_POWER_DOWN, 0, 0);
-	for (;;)
-		;
-}
-
-static void msm_pm_restart(char str, const char *cmd)
-{
-	msm_rpcrouter_close();
-	msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0);
-
-	for (;;)
-		;
-}
-
-static int msm_reboot_call
-	(struct notifier_block *this, unsigned long code, void *_cmd)
-{
-	if ((code == SYS_RESTART) && _cmd) {
-		char *cmd = _cmd;
-		if (!strcmp(cmd, "bootloader")) {
-			restart_reason = 0x77665500;
-		} else if (!strcmp(cmd, "recovery")) {
-			restart_reason = 0x77665502;
-		} else if (!strcmp(cmd, "eraseflash")) {
-			restart_reason = 0x776655EF;
-		} else if (!strncmp(cmd, "oem-", 4)) {
-			unsigned code = simple_strtoul(cmd + 4, 0, 16) & 0xff;
-			restart_reason = 0x6f656d00 | code;
-		} else {
-			restart_reason = 0x77665501;
-		}
-	}
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block msm_reboot_notifier = {
-	.notifier_call = msm_reboot_call,
-};
-
-
 /*
  * Initialize the power management subsystem.
  *
@@ -1693,10 +1641,6 @@
 		     virt_to_phys(&msm_pm_pc_pgd));
 #endif
 
-	pm_power_off = msm_pm_power_off;
-	arm_pm_restart = msm_pm_restart;
-	register_reboot_notifier(&msm_reboot_notifier);
-
 	msm_pm_smem_data = smem_alloc(SMEM_APPS_DEM_SLAVE_DATA,
 		sizeof(*msm_pm_smem_data));
 	if (msm_pm_smem_data == NULL) {
diff --git a/arch/arm/mach-msm/restart_7k.c b/arch/arm/mach-msm/restart_7k.c
new file mode 100644
index 0000000..dc9edf4
--- /dev/null
+++ b/arch/arm/mach-msm/restart_7k.c
@@ -0,0 +1,101 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+#include <linux/pm.h>
+#include <asm/system_misc.h>
+#include <mach/proc_comm.h>
+
+#include "devices-msm7x2xa.h"
+#include "smd_rpcrouter.h"
+
+static uint32_t restart_reason = 0x776655AA;
+
+static void msm_pm_power_off(void)
+{
+	msm_rpcrouter_close();
+	msm_proc_comm(PCOM_POWER_DOWN, 0, 0);
+	for (;;)
+		;
+}
+
+static void msm_pm_restart(char str, const char *cmd)
+{
+	msm_rpcrouter_close();
+	pr_debug("The reset reason is %x\n", restart_reason);
+
+	/* Disable interrupts */
+	local_irq_disable();
+	local_fiq_disable();
+
+	/*
+	 * Take out a flat memory mapping  and will
+	 * insert a 1:1 mapping in place of
+	 * the user-mode pages to ensure predictable results
+	 * This function takes care of flushing the caches
+	 * and flushing the TLB.
+	 */
+	setup_mm_for_reboot();
+
+	msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0);
+
+	for (;;)
+		;
+}
+
+static int msm_reboot_call
+	(struct notifier_block *this, unsigned long code, void *_cmd)
+{
+	if ((code == SYS_RESTART) && _cmd) {
+		char *cmd = _cmd;
+		if (!strncmp(cmd, "bootloader", 10)) {
+			restart_reason = 0x77665500;
+		} else if (!strncmp(cmd, "recovery", 8)) {
+			restart_reason = 0x77665502;
+		} else if (!strncmp(cmd, "eraseflash", 10)) {
+			restart_reason = 0x776655EF;
+		} else if (!strncmp(cmd, "oem-", 4)) {
+			unsigned long code;
+			int res;
+			res = kstrtoul(cmd + 4, 16, &code);
+			code &= 0xff;
+			restart_reason = 0x6f656d00 | code;
+		} else {
+			restart_reason = 0x77665501;
+		}
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block msm_reboot_notifier = {
+	.notifier_call = msm_reboot_call,
+};
+
+static int __init msm_pm_restart_init(void)
+{
+	int ret;
+
+	pm_power_off = msm_pm_power_off;
+	arm_pm_restart = msm_pm_restart;
+
+	ret = register_reboot_notifier(&msm_reboot_notifier);
+	if (ret)
+		pr_err("Failed to register reboot notifier\n");
+
+	return ret;
+}
+late_initcall(msm_pm_restart_init);