aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
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-04-08 15:43:08 -0400
commitbc34b5f27cd33f4213bc5c8df0099dd11408d29d (patch)
tree0e919c251b0ce51592d4e99ee8161bfdf752de0b /arch/arm
parentd7fbc6ca35db027345a0e066c54b367e31d4fed3 (diff)
ARM: sunxi: Rework the restart code
The Allwinner sun6i (A31) has a slightly different watchdog, that doesn't allow to use the already existing restart code. Rework a bit the restart code to allow to plug in more easily different restart handlers depending on the device tree. In the past, we were also meaning sunxi as a generic name covering all Allwinner SoCs. This won't be true anymore with the A31 (sun6i) that differs pretty much from sun4i and sun5i, and we will end up having sunxi, for sun4i and sun5i, and sun6i, which is neither consistent nor convenient. So, while we're at it, also change sunxi to sun4i. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-sunxi/sunxi.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index c99ab1bdee4d..706ce35396b8 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -24,50 +24,63 @@
24 24
25#include <asm/mach/arch.h> 25#include <asm/mach/arch.h>
26#include <asm/mach/map.h> 26#include <asm/mach/map.h>
27#include <asm/system_misc.h>
27 28
28#include "sunxi.h" 29#include "sunxi.h"
29 30
30#define WATCHDOG_CTRL_REG 0x00 31#define SUN4I_WATCHDOG_CTRL_REG 0x00
31#define WATCHDOG_CTRL_RESTART (1 << 0) 32#define SUN4I_WATCHDOG_CTRL_RESTART (1 << 0)
32#define WATCHDOG_MODE_REG 0x04 33#define SUN4I_WATCHDOG_MODE_REG 0x04
33#define WATCHDOG_MODE_ENABLE (1 << 0) 34#define SUN4I_WATCHDOG_MODE_ENABLE (1 << 0)
34#define WATCHDOG_MODE_RESET_ENABLE (1 << 1) 35#define SUN4I_WATCHDOG_MODE_RESET_ENABLE (1 << 1)
35 36
36static void __iomem *wdt_base; 37static void __iomem *wdt_base;
37 38
38static void sunxi_setup_restart(void) 39static void sun4i_restart(char mode, const char *cmd)
39{
40 struct device_node *np = of_find_compatible_node(NULL, NULL,
41 "allwinner,sunxi-wdt");
42 if (WARN(!np, "unable to setup watchdog restart"))
43 return;
44
45 wdt_base = of_iomap(np, 0);
46 WARN(!wdt_base, "failed to map watchdog base address");
47}
48
49static void sunxi_restart(char mode, const char *cmd)
50{ 40{
51 if (!wdt_base) 41 if (!wdt_base)
52 return; 42 return;
53 43
54 /* Enable timer and set reset bit in the watchdog */ 44 /* Enable timer and set reset bit in the watchdog */
55 writel(WATCHDOG_MODE_ENABLE | WATCHDOG_MODE_RESET_ENABLE, 45 writel(SUN4I_WATCHDOG_MODE_ENABLE | SUN4I_WATCHDOG_MODE_RESET_ENABLE,
56 wdt_base + WATCHDOG_MODE_REG); 46 wdt_base + SUN4I_WATCHDOG_MODE_REG);
57 47
58 /* 48 /*
59 * Restart the watchdog. The default (and lowest) interval 49 * Restart the watchdog. The default (and lowest) interval
60 * value for the watchdog is 0.5s. 50 * value for the watchdog is 0.5s.
61 */ 51 */
62 writel(WATCHDOG_CTRL_RESTART, wdt_base + WATCHDOG_CTRL_REG); 52 writel(SUN4I_WATCHDOG_CTRL_RESTART, wdt_base + SUN4I_WATCHDOG_CTRL_REG);
63 53
64 while (1) { 54 while (1) {
65 mdelay(5); 55 mdelay(5);
66 writel(WATCHDOG_MODE_ENABLE | WATCHDOG_MODE_RESET_ENABLE, 56 writel(SUN4I_WATCHDOG_MODE_ENABLE | SUN4I_WATCHDOG_MODE_RESET_ENABLE,
67 wdt_base + WATCHDOG_MODE_REG); 57 wdt_base + SUN4I_WATCHDOG_MODE_REG);
68 } 58 }
69} 59}
70 60
61static struct of_device_id sunxi_restart_ids[] = {
62 { .compatible = "allwinner,sun4i-wdt", .data = sun4i_restart },
63 { /*sentinel*/ }
64};
65
66static void sunxi_setup_restart(void)
67{
68 const struct of_device_id *of_id;
69 struct device_node *np;
70
71 np = of_find_matching_node(NULL, sunxi_restart_ids);
72 if (WARN(!np, "unable to setup watchdog restart"))
73 return;
74
75 wdt_base = of_iomap(np, 0);
76 WARN(!wdt_base, "failed to map watchdog base address");
77
78 of_id = of_match_node(sunxi_restart_ids, np);
79 WARN(!of_id, "restart function not available");
80
81 arm_pm_restart = of_id->data;
82}
83
71static struct map_desc sunxi_io_desc[] __initdata = { 84static struct map_desc sunxi_io_desc[] __initdata = {
72 { 85 {
73 .virtual = (unsigned long) SUNXI_REGS_VIRT_BASE, 86 .virtual = (unsigned long) SUNXI_REGS_VIRT_BASE,
@@ -105,7 +118,6 @@ DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
105 .init_machine = sunxi_dt_init, 118 .init_machine = sunxi_dt_init,
106 .map_io = sunxi_map_io, 119 .map_io = sunxi_map_io,
107 .init_irq = irqchip_init, 120 .init_irq = irqchip_init,
108 .restart = sunxi_restart,
109 .init_time = sunxi_timer_init, 121 .init_time = sunxi_timer_init,
110 .dt_compat = sunxi_board_dt_compat, 122 .dt_compat = sunxi_board_dt_compat,
111MACHINE_END 123MACHINE_END