aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-sunxi
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2013-03-11 15:21:11 -0400
committerMaxime Ripard <maxime.ripard@free-electrons.com>2013-08-16 17:19:30 -0400
commit06d71bcfee91b2be105f43c85fcd3960e179818b (patch)
treeaefe974c11bf22236ffd9a814a8939797d940ec0 /arch/arm/mach-sunxi
parent2d7945100b1ade1de73ddc397c17d0c40b278fb4 (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.c43
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
35static void __iomem *wdt_base; 44static 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
68static 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
59static struct of_device_id sunxi_restart_ids[] = { 95static 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