diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2013-03-11 15:21:11 -0400 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@free-electrons.com> | 2013-08-16 17:19:30 -0400 |
commit | 06d71bcfee91b2be105f43c85fcd3960e179818b (patch) | |
tree | aefe974c11bf22236ffd9a814a8939797d940ec0 /arch/arm/mach-sunxi | |
parent | 2d7945100b1ade1de73ddc397c17d0c40b278fb4 (diff) |
ARM: sun6i: Add restart code for the A31
The Allwinner A31 has a different watchdog, with a slightly different
register layout, that requires a different restart code.
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 | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index 11326d9f13da..223995e0481f 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c | |||
@@ -27,10 +27,19 @@ | |||
27 | #include <asm/system_misc.h> | 27 | #include <asm/system_misc.h> |
28 | 28 | ||
29 | #define SUN4I_WATCHDOG_CTRL_REG 0x00 | 29 | #define SUN4I_WATCHDOG_CTRL_REG 0x00 |
30 | #define SUN4I_WATCHDOG_CTRL_RESTART (1 << 0) | 30 | #define SUN4I_WATCHDOG_CTRL_RESTART BIT(0) |
31 | #define SUN4I_WATCHDOG_MODE_REG 0x04 | 31 | #define SUN4I_WATCHDOG_MODE_REG 0x04 |
32 | #define SUN4I_WATCHDOG_MODE_ENABLE (1 << 0) | 32 | #define SUN4I_WATCHDOG_MODE_ENABLE BIT(0) |
33 | #define SUN4I_WATCHDOG_MODE_RESET_ENABLE (1 << 1) | 33 | #define SUN4I_WATCHDOG_MODE_RESET_ENABLE BIT(1) |
34 | |||
35 | #define SUN6I_WATCHDOG1_IRQ_REG 0x00 | ||
36 | #define SUN6I_WATCHDOG1_CTRL_REG 0x10 | ||
37 | #define SUN6I_WATCHDOG1_CTRL_RESTART BIT(0) | ||
38 | #define SUN6I_WATCHDOG1_CONFIG_REG 0x14 | ||
39 | #define SUN6I_WATCHDOG1_CONFIG_RESTART BIT(0) | ||
40 | #define SUN6I_WATCHDOG1_CONFIG_IRQ BIT(1) | ||
41 | #define SUN6I_WATCHDOG1_MODE_REG 0x18 | ||
42 | #define SUN6I_WATCHDOG1_MODE_ENABLE BIT(0) | ||
34 | 43 | ||
35 | static void __iomem *wdt_base; | 44 | static void __iomem *wdt_base; |
36 | 45 | ||
@@ -56,8 +65,36 @@ static void sun4i_restart(enum reboot_mode mode, const char *cmd) | |||
56 | } | 65 | } |
57 | } | 66 | } |
58 | 67 | ||
68 | static void sun6i_restart(enum reboot_mode mode, const char *cmd) | ||
69 | { | ||
70 | if (!wdt_base) | ||
71 | return; | ||
72 | |||
73 | /* Disable interrupts */ | ||
74 | writel(0, wdt_base + SUN6I_WATCHDOG1_IRQ_REG); | ||
75 | |||
76 | /* We want to disable the IRQ and just reset the whole system */ | ||
77 | writel(SUN6I_WATCHDOG1_CONFIG_RESTART, | ||
78 | wdt_base + SUN6I_WATCHDOG1_CONFIG_REG); | ||
79 | |||
80 | /* Enable timer. The default and lowest interval value is 0.5s */ | ||
81 | writel(SUN6I_WATCHDOG1_MODE_ENABLE, | ||
82 | wdt_base + SUN6I_WATCHDOG1_MODE_REG); | ||
83 | |||
84 | /* Restart the watchdog. */ | ||
85 | writel(SUN6I_WATCHDOG1_CTRL_RESTART, | ||
86 | wdt_base + SUN6I_WATCHDOG1_CTRL_REG); | ||
87 | |||
88 | while (1) { | ||
89 | mdelay(5); | ||
90 | writel(SUN6I_WATCHDOG1_MODE_ENABLE, | ||
91 | wdt_base + SUN6I_WATCHDOG1_MODE_REG); | ||
92 | } | ||
93 | } | ||
94 | |||
59 | static struct of_device_id sunxi_restart_ids[] = { | 95 | static struct of_device_id sunxi_restart_ids[] = { |
60 | { .compatible = "allwinner,sun4i-wdt", .data = sun4i_restart }, | 96 | { .compatible = "allwinner,sun4i-wdt", .data = sun4i_restart }, |
97 | { .compatible = "allwinner,sun6i-wdt", .data = sun6i_restart }, | ||
61 | { /*sentinel*/ } | 98 | { /*sentinel*/ } |
62 | }; | 99 | }; |
63 | 100 | ||