PageRenderTime 28ms CodeModel.GetById 20ms app.highlight 6ms RepoModel.GetById 0ms app.codeStats 0ms

/arch/arm/mach-msm/restart.c

https://bitbucket.org/sammyz/iscream_thunderc-2.6.35-rebase
C | 136 lines | 97 code | 22 blank | 17 comment | 11 complexity | a1b3800a3ce6cb0ea95510d191ea57df MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  2 *
  3 * This program is free software; you can redistribute it and/or modify
  4 * it under the terms of the GNU General Public License version 2 and
  5 * only version 2 as published by the Free Software Foundation.
  6 *
  7 * This program is distributed in the hope that it will be useful,
  8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10 * GNU General Public License for more details.
 11 *
 12 * You should have received a copy of the GNU General Public License
 13 * along with this program; if not, write to the Free Software
 14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 15 * 02110-1301, USA.
 16 *
 17 */
 18
 19#include <linux/module.h>
 20#include <linux/kernel.h>
 21#include <linux/init.h>
 22#include <linux/reboot.h>
 23#include <linux/io.h>
 24#include <linux/delay.h>
 25#include <linux/pm.h>
 26#include <linux/mfd/pmic8058.h>
 27#include <linux/mfd/pmic8901.h>
 28
 29#include <mach/msm_iomap.h>
 30#include <mach/scm-io.h>
 31
 32#define TCSR_WDT_CFG 0x30
 33
 34#define WDT0_RST       (MSM_TMR0_BASE + 0x38)
 35#define WDT0_EN        (MSM_TMR0_BASE + 0x40)
 36#define WDT0_BARK_TIME (MSM_TMR0_BASE + 0x4C)
 37#define WDT0_BITE_TIME (MSM_TMR0_BASE + 0x5C)
 38
 39#define PSHOLD_CTL_SU (MSM_TLMM_BASE + 0x820)
 40
 41#define RESTART_REASON_ADDR 0x2A05F65C
 42
 43#ifdef CONFIG_MSM_DLOAD_MODE
 44static int in_panic;
 45
 46static int panic_prep_restart(struct notifier_block *this,
 47			      unsigned long event, void *ptr)
 48{
 49	in_panic = 1;
 50	return NOTIFY_DONE;
 51}
 52
 53static struct notifier_block panic_blk = {
 54	.notifier_call	= panic_prep_restart,
 55};
 56
 57static void set_dload_mode(int on)
 58{
 59	void *dload_mode_addr;
 60	dload_mode_addr = ioremap_nocache(0x2A05F000, SZ_4K);
 61	if (dload_mode_addr) {
 62		writel(on ? 0xE47B337D : 0, dload_mode_addr);
 63		writel(on ? 0xCE14091A : 0,
 64		       dload_mode_addr + sizeof(unsigned int));
 65		dmb();
 66		iounmap(dload_mode_addr);
 67	}
 68}
 69#else
 70#define set_dload_mode(x) do {} while (0)
 71#endif
 72
 73static void msm_power_off(void)
 74{
 75	printk(KERN_NOTICE "Powering off the SoC\n");
 76	pm8058_reset_pwr_off(0);
 77	pm8901_reset_pwr_off(0);
 78	writel(0, PSHOLD_CTL_SU);
 79	mdelay(10000);
 80	printk(KERN_ERR "Powering off has failed\n");
 81	return;
 82}
 83
 84void arch_reset(char mode, const char *cmd)
 85{
 86	void *restart_reason;
 87
 88#ifdef CONFIG_MSM_DLOAD_MODE
 89	if (in_panic)
 90		set_dload_mode(1);
 91#endif
 92
 93	printk(KERN_NOTICE "Going down for restart now\n");
 94
 95	pm8058_reset_pwr_off(1);
 96
 97	if (cmd != NULL) {
 98		restart_reason = ioremap_nocache(RESTART_REASON_ADDR, SZ_4K);
 99		if (!strncmp(cmd, "bootloader", 10)) {
100			writel(0x77665500, restart_reason);
101		} else if (!strncmp(cmd, "recovery", 8)) {
102			writel(0x77665502, restart_reason);
103		} else if (!strncmp(cmd, "oem-", 4)) {
104			unsigned long code;
105			strict_strtoul(cmd + 4, 16, &code);
106			code = code & 0xff;
107			writel(0x6f656d00 | code, restart_reason);
108		} else {
109			writel(0x77665501, restart_reason);
110		}
111		iounmap(restart_reason);
112	}
113
114	writel(1, WDT0_RST);
115	writel(0, WDT0_EN);
116	writel(0x31F3, WDT0_BARK_TIME);
117	writel(0x31F3, WDT0_BITE_TIME);
118	writel(3, WDT0_EN);
119	dmb();
120	secure_writel(3, MSM_TCSR_BASE + TCSR_WDT_CFG);
121
122	mdelay(10000);
123}
124
125static int __init msm_restart_init(void)
126{
127#ifdef CONFIG_MSM_DLOAD_MODE
128	atomic_notifier_chain_register(&panic_notifier_list, &panic_blk);
129#endif
130
131	pm_power_off = msm_power_off;
132
133	return 0;
134}
135
136late_initcall(msm_restart_init);