Commit | Line | Data |
---|---|---|
af75655c JI |
1 | /* |
2 | * Copyright (c) 2011 Picochip Ltd., Jamie Iles | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License version 2 as | |
6 | * published by the Free Software Foundation. | |
7 | * | |
8 | * All enquiries to support@picochip.com | |
9 | */ | |
1b46f878 | 10 | #include <linux/delay.h> |
af75655c JI |
11 | #include <linux/of.h> |
12 | #include <linux/of_address.h> | |
7b6d864b | 13 | #include <linux/reboot.h> |
af75655c JI |
14 | |
15 | #include <asm/mach/arch.h> | |
8f37a0b4 | 16 | #include <asm/mach/map.h> |
af75655c | 17 | |
06413f1e RH |
18 | #define PHYS_TO_IO(x) (((x) & 0x00ffffff) | 0xfe000000) |
19 | #define PICOXCELL_PERIPH_BASE 0x80000000 | |
20 | #define PICOXCELL_PERIPH_LENGTH SZ_4M | |
21 | ||
22 | #define WDT_CTRL_REG_EN_MASK (1 << 0) | |
23 | #define WDT_CTRL_REG_OFFS (0x00) | |
24 | #define WDT_TIMEOUT_REG_OFFS (0x04) | |
1b46f878 JI |
25 | static void __iomem *wdt_regs; |
26 | ||
27 | /* | |
28 | * The machine restart method can be called from an atomic context so we won't | |
29 | * be able to ioremap the regs then. | |
30 | */ | |
31 | static void picoxcell_setup_restart(void) | |
32 | { | |
33 | struct device_node *np = of_find_compatible_node(NULL, NULL, | |
34 | "snps,dw-apb-wdg"); | |
35 | if (WARN(!np, "unable to setup watchdog restart")) | |
36 | return; | |
37 | ||
38 | wdt_regs = of_iomap(np, 0); | |
39 | WARN(!wdt_regs, "failed to remap watchdog regs"); | |
40 | } | |
41 | ||
8f37a0b4 JI |
42 | static struct map_desc io_map __initdata = { |
43 | .virtual = PHYS_TO_IO(PICOXCELL_PERIPH_BASE), | |
44 | .pfn = __phys_to_pfn(PICOXCELL_PERIPH_BASE), | |
45 | .length = PICOXCELL_PERIPH_LENGTH, | |
46 | .type = MT_DEVICE, | |
47 | }; | |
48 | ||
49 | static void __init picoxcell_map_io(void) | |
50 | { | |
51 | iotable_init(&io_map, 1); | |
52 | } | |
53 | ||
af75655c JI |
54 | static void __init picoxcell_init_machine(void) |
55 | { | |
1b46f878 | 56 | picoxcell_setup_restart(); |
af75655c JI |
57 | } |
58 | ||
59 | static const char *picoxcell_dt_match[] = { | |
60 | "picochip,pc3x2", | |
61 | "picochip,pc3x3", | |
62 | NULL | |
63 | }; | |
64 | ||
7b6d864b | 65 | static void picoxcell_wdt_restart(enum reboot_mode mode, const char *cmd) |
1b46f878 JI |
66 | { |
67 | /* | |
68 | * Configure the watchdog to reset with the shortest possible timeout | |
69 | * and give it chance to do the reset. | |
70 | */ | |
71 | if (wdt_regs) { | |
72 | writel_relaxed(WDT_CTRL_REG_EN_MASK, wdt_regs + WDT_CTRL_REG_OFFS); | |
73 | writel_relaxed(0, wdt_regs + WDT_TIMEOUT_REG_OFFS); | |
74 | /* No sleeping, possibly atomic. */ | |
75 | mdelay(500); | |
76 | } | |
77 | } | |
78 | ||
af75655c JI |
79 | DT_MACHINE_START(PICOXCELL, "Picochip picoXcell") |
80 | .map_io = picoxcell_map_io, | |
af75655c JI |
81 | .init_machine = picoxcell_init_machine, |
82 | .dt_compat = picoxcell_dt_match, | |
1b46f878 | 83 | .restart = picoxcell_wdt_restart, |
af75655c | 84 | MACHINE_END |