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> | |
13 | #include <linux/of_platform.h> | |
7b6d864b | 14 | #include <linux/reboot.h> |
af75655c JI |
15 | |
16 | #include <asm/mach/arch.h> | |
8f37a0b4 | 17 | #include <asm/mach/map.h> |
af75655c | 18 | |
06413f1e RH |
19 | #define PHYS_TO_IO(x) (((x) & 0x00ffffff) | 0xfe000000) |
20 | #define PICOXCELL_PERIPH_BASE 0x80000000 | |
21 | #define PICOXCELL_PERIPH_LENGTH SZ_4M | |
22 | ||
23 | #define WDT_CTRL_REG_EN_MASK (1 << 0) | |
24 | #define WDT_CTRL_REG_OFFS (0x00) | |
25 | #define WDT_TIMEOUT_REG_OFFS (0x04) | |
1b46f878 JI |
26 | static void __iomem *wdt_regs; |
27 | ||
28 | /* | |
29 | * The machine restart method can be called from an atomic context so we won't | |
30 | * be able to ioremap the regs then. | |
31 | */ | |
32 | static void picoxcell_setup_restart(void) | |
33 | { | |
34 | struct device_node *np = of_find_compatible_node(NULL, NULL, | |
35 | "snps,dw-apb-wdg"); | |
36 | if (WARN(!np, "unable to setup watchdog restart")) | |
37 | return; | |
38 | ||
39 | wdt_regs = of_iomap(np, 0); | |
40 | WARN(!wdt_regs, "failed to remap watchdog regs"); | |
41 | } | |
42 | ||
8f37a0b4 JI |
43 | static struct map_desc io_map __initdata = { |
44 | .virtual = PHYS_TO_IO(PICOXCELL_PERIPH_BASE), | |
45 | .pfn = __phys_to_pfn(PICOXCELL_PERIPH_BASE), | |
46 | .length = PICOXCELL_PERIPH_LENGTH, | |
47 | .type = MT_DEVICE, | |
48 | }; | |
49 | ||
50 | static void __init picoxcell_map_io(void) | |
51 | { | |
52 | iotable_init(&io_map, 1); | |
53 | } | |
54 | ||
af75655c JI |
55 | static void __init picoxcell_init_machine(void) |
56 | { | |
57 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | |
1b46f878 | 58 | picoxcell_setup_restart(); |
af75655c JI |
59 | } |
60 | ||
61 | static const char *picoxcell_dt_match[] = { | |
62 | "picochip,pc3x2", | |
63 | "picochip,pc3x3", | |
64 | NULL | |
65 | }; | |
66 | ||
7b6d864b | 67 | static void picoxcell_wdt_restart(enum reboot_mode mode, const char *cmd) |
1b46f878 JI |
68 | { |
69 | /* | |
70 | * Configure the watchdog to reset with the shortest possible timeout | |
71 | * and give it chance to do the reset. | |
72 | */ | |
73 | if (wdt_regs) { | |
74 | writel_relaxed(WDT_CTRL_REG_EN_MASK, wdt_regs + WDT_CTRL_REG_OFFS); | |
75 | writel_relaxed(0, wdt_regs + WDT_TIMEOUT_REG_OFFS); | |
76 | /* No sleeping, possibly atomic. */ | |
77 | mdelay(500); | |
78 | } | |
79 | } | |
80 | ||
af75655c JI |
81 | DT_MACHINE_START(PICOXCELL, "Picochip picoXcell") |
82 | .map_io = picoxcell_map_io, | |
af75655c JI |
83 | .init_machine = picoxcell_init_machine, |
84 | .dt_compat = picoxcell_dt_match, | |
1b46f878 | 85 | .restart = picoxcell_wdt_restart, |
af75655c | 86 | MACHINE_END |