aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/wdt-recovery.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/mach-tegra/wdt-recovery.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'arch/arm/mach-tegra/wdt-recovery.c')
-rw-r--r--arch/arm/mach-tegra/wdt-recovery.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/wdt-recovery.c b/arch/arm/mach-tegra/wdt-recovery.c
new file mode 100644
index 00000000000..537b1c0db85
--- /dev/null
+++ b/arch/arm/mach-tegra/wdt-recovery.c
@@ -0,0 +1,131 @@
1/*
2 * arch/arm/mach-tegra/wdt-recovery.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#include <linux/kernel.h>
21#include <linux/delay.h>
22#include <linux/suspend.h>
23#include <linux/resource.h>
24#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/syscore_ops.h>
27#include <linux/io.h>
28
29#include <asm/mach-types.h>
30#include <asm/mach/time.h>
31#include <asm/localtimer.h>
32
33#include <mach/nvmap.h>
34#include <mach/irqs.h>
35#include <mach/iomap.h>
36#include <mach/clk.h>
37#include <mach/io.h>
38
39static int wdt_heartbeat = 30;
40
41#if defined(CONFIG_ARCH_TEGRA_3x_SOC)
42#define TIMER_PTV 0
43 #define TIMER_EN (1 << 31)
44 #define TIMER_PERIODIC (1 << 30)
45#define TIMER_PCR 0x4
46 #define TIMER_PCR_INTR (1 << 30)
47#define WDT_CFG (0)
48 #define WDT_CFG_TMR_SRC (7 << 0) /* for TMR7. */
49 #define WDT_CFG_PERIOD (1 << 4)
50 #define WDT_CFG_INT_EN (1 << 12)
51 #define WDT_CFG_SYS_RST_EN (1 << 14)
52 #define WDT_CFG_PMC2CAR_RST_EN (1 << 15)
53#define WDT_CMD (8)
54 #define WDT_CMD_START_COUNTER (1 << 0)
55 #define WDT_CMD_DISABLE_COUNTER (1 << 1)
56#define WDT_UNLOCK (0xC)
57 #define WDT_UNLOCK_PATTERN (0xC45A << 0)
58
59static void __iomem *wdt_timer = IO_ADDRESS(TEGRA_TMR7_BASE);
60static void __iomem *wdt_source = IO_ADDRESS(TEGRA_WDT0_BASE);
61
62static void tegra_wdt_reset_enable(void)
63{
64 u32 val;
65
66 writel(TIMER_PCR_INTR, wdt_timer + TIMER_PCR);
67 val = (wdt_heartbeat * 1000000ul) / 4;
68 val |= (TIMER_EN | TIMER_PERIODIC);
69 writel(val, wdt_timer + TIMER_PTV);
70
71 val = WDT_CFG_TMR_SRC | WDT_CFG_PERIOD | /*WDT_CFG_INT_EN |*/
72 /*WDT_CFG_SYS_RST_EN |*/ WDT_CFG_PMC2CAR_RST_EN;
73 writel(val, wdt_source + WDT_CFG);
74 writel(WDT_CMD_START_COUNTER, wdt_source + WDT_CMD);
75 pr_info("%s: WDT Recovery Enabled\n", __func__);
76}
77
78static int tegra_wdt_reset_disable(void)
79{
80 writel(TIMER_PCR_INTR, wdt_timer + TIMER_PCR);
81 writel(WDT_UNLOCK_PATTERN, wdt_source + WDT_UNLOCK);
82 writel(WDT_CMD_DISABLE_COUNTER, wdt_source + WDT_CMD);
83
84 writel(0, wdt_timer + TIMER_PTV);
85 pr_info("%s: WDT Recovery Disabled\n", __func__);
86
87 return 0;
88}
89#elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
90
91static void tegra_wdt_reset_enable(void)
92{
93}
94static int tegra_wdt_reset_disable(void)
95{
96 return 0;
97}
98#endif
99
100static int tegra_pm_notify(struct notifier_block *nb,
101 unsigned long event, void *nouse)
102{
103 switch (event) {
104 case PM_SUSPEND_PREPARE:
105 tegra_wdt_reset_enable();
106 break;
107 case PM_POST_SUSPEND:
108 tegra_wdt_reset_disable();
109 break;
110 }
111
112 return NOTIFY_OK;
113}
114
115static struct notifier_block tegra_wdt_notify = {
116 .notifier_call = tegra_pm_notify,
117};
118
119static struct syscore_ops tegra_wdt_syscore_ops = {
120 .suspend = tegra_wdt_reset_disable,
121 .resume = tegra_wdt_reset_enable,
122};
123
124void __init tegra_wdt_recovery_init(void)
125{
126#ifdef CONFIG_PM
127 /* Register PM notifier. */
128 register_pm_notifier(&tegra_wdt_notify);
129#endif
130 register_syscore_ops(&tegra_wdt_syscore_ops);
131}