diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2012-11-19 12:57:08 -0500 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@free-electrons.com> | 2012-11-21 03:25:25 -0500 |
commit | 67bea88dd842deb3ed8327ad101970dbd615ddcb (patch) | |
tree | b13cb72433c2289d1c67f3bad7733350fa02de14 /arch/arm/mach-sunxi | |
parent | f055f1f682b84b3b785813f5c11efacab6001253 (diff) |
ARM: sunxi: Add sunxi restart function via onchip watchdog
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Diffstat (limited to 'arch/arm/mach-sunxi')
-rw-r--r-- | arch/arm/mach-sunxi/sunxi.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index 13d4d96cbc85..dc634ae2081f 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/of_address.h> | ||
15 | #include <linux/of_irq.h> | 16 | #include <linux/of_irq.h> |
16 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
17 | #include <linux/io.h> | 18 | #include <linux/io.h> |
@@ -26,6 +27,36 @@ | |||
26 | 27 | ||
27 | #include "sunxi.h" | 28 | #include "sunxi.h" |
28 | 29 | ||
30 | #define WATCHDOG_CTRL_REG 0x00 | ||
31 | #define WATCHDOG_MODE_REG 0x04 | ||
32 | |||
33 | static void __iomem *wdt_base; | ||
34 | |||
35 | static void sunxi_setup_restart(void) | ||
36 | { | ||
37 | struct device_node *np = of_find_compatible_node(NULL, NULL, | ||
38 | "allwinner,sunxi-wdt"); | ||
39 | if (WARN(!np, "unable to setup watchdog restart")) | ||
40 | return; | ||
41 | |||
42 | wdt_base = of_iomap(np, 0); | ||
43 | WARN(!wdt_base, "failed to map watchdog base address"); | ||
44 | } | ||
45 | |||
46 | static void sunxi_restart(char mode, const char *cmd) | ||
47 | { | ||
48 | if (!wdt_base) | ||
49 | return; | ||
50 | |||
51 | /* Enable timer and set reset bit in the watchdog */ | ||
52 | writel(3, wdt_base + WATCHDOG_MODE_REG); | ||
53 | writel(0xa57 << 1 | 1, wdt_base + WATCHDOG_CTRL_REG); | ||
54 | while(1) { | ||
55 | mdelay(5); | ||
56 | writel(3, wdt_base + WATCHDOG_MODE_REG); | ||
57 | } | ||
58 | } | ||
59 | |||
29 | static struct map_desc sunxi_io_desc[] __initdata = { | 60 | static struct map_desc sunxi_io_desc[] __initdata = { |
30 | { | 61 | { |
31 | .virtual = (unsigned long) SUNXI_REGS_VIRT_BASE, | 62 | .virtual = (unsigned long) SUNXI_REGS_VIRT_BASE, |
@@ -42,6 +73,8 @@ void __init sunxi_map_io(void) | |||
42 | 73 | ||
43 | static void __init sunxi_dt_init(void) | 74 | static void __init sunxi_dt_init(void) |
44 | { | 75 | { |
76 | sunxi_setup_restart(); | ||
77 | |||
45 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 78 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
46 | } | 79 | } |
47 | 80 | ||
@@ -56,6 +89,7 @@ DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)") | |||
56 | .map_io = sunxi_map_io, | 89 | .map_io = sunxi_map_io, |
57 | .init_irq = sunxi_init_irq, | 90 | .init_irq = sunxi_init_irq, |
58 | .handle_irq = sunxi_handle_irq, | 91 | .handle_irq = sunxi_handle_irq, |
92 | .restart = sunxi_restart, | ||
59 | .timer = &sunxi_timer, | 93 | .timer = &sunxi_timer, |
60 | .dt_compat = sunxi_board_dt_compat, | 94 | .dt_compat = sunxi_board_dt_compat, |
61 | MACHINE_END | 95 | MACHINE_END |