diff options
author | Marian Balakowicz <m8@semihalf.com> | 2007-10-18 14:44:33 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2007-10-21 14:43:04 -0400 |
commit | 86b92cdda9e997dd305851cb16292c67076d58cb (patch) | |
tree | 6acfde248f5638e666442ef305347d190a50e115 /arch/powerpc | |
parent | d24bc314c964e900ddf30efa1ef44565cf0cf44c (diff) |
[POWERPC] Add restart support for mpc52xx based platforms
Add common helper routines: mpc52xx_map_wdt() and mpc52xx_restart().
Signed-off-by: Marian Balakowicz <m8@semihalf.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/52xx/mpc52xx_common.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 74b4b4183842..9850685c5429 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c | |||
@@ -18,6 +18,13 @@ | |||
18 | #include <asm/prom.h> | 18 | #include <asm/prom.h> |
19 | #include <asm/mpc52xx.h> | 19 | #include <asm/mpc52xx.h> |
20 | 20 | ||
21 | /* | ||
22 | * This variable is mapped in mpc52xx_map_wdt() and used in mpc52xx_restart(). | ||
23 | * Permanent mapping is required because mpc52xx_restart() can be called | ||
24 | * from interrupt context while node mapping (which calls ioremap()) | ||
25 | * cannot be used at such point. | ||
26 | */ | ||
27 | static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL; | ||
21 | 28 | ||
22 | static void __iomem * | 29 | static void __iomem * |
23 | mpc52xx_map_node(struct device_node *ofn) | 30 | mpc52xx_map_node(struct device_node *ofn) |
@@ -126,3 +133,46 @@ mpc52xx_declare_of_platform_devices(void) | |||
126 | "Error while probing of_platform bus\n"); | 133 | "Error while probing of_platform bus\n"); |
127 | } | 134 | } |
128 | 135 | ||
136 | void __init | ||
137 | mpc52xx_map_wdt(void) | ||
138 | { | ||
139 | const void *has_wdt; | ||
140 | struct device_node *np; | ||
141 | |||
142 | /* mpc52xx_wdt is mapped here and used in mpc52xx_restart, | ||
143 | * possibly from a interrupt context. wdt is only implement | ||
144 | * on a gpt0, so check has-wdt property before mapping. | ||
145 | */ | ||
146 | for_each_compatible_node(np, NULL, "fsl,mpc5200-gpt") { | ||
147 | has_wdt = of_get_property(np, "fsl,has-wdt", NULL); | ||
148 | if (has_wdt) { | ||
149 | mpc52xx_wdt = mpc52xx_map_node(np); | ||
150 | return; | ||
151 | } | ||
152 | } | ||
153 | for_each_compatible_node(np, NULL, "mpc5200-gpt") { | ||
154 | has_wdt = of_get_property(np, "has-wdt", NULL); | ||
155 | if (has_wdt) { | ||
156 | mpc52xx_wdt = mpc52xx_map_node(np); | ||
157 | return; | ||
158 | } | ||
159 | } | ||
160 | } | ||
161 | |||
162 | void | ||
163 | mpc52xx_restart(char *cmd) | ||
164 | { | ||
165 | local_irq_disable(); | ||
166 | |||
167 | /* Turn on the watchdog and wait for it to expire. | ||
168 | * It effectively does a reset. */ | ||
169 | if (mpc52xx_wdt) { | ||
170 | out_be32(&mpc52xx_wdt->mode, 0x00000000); | ||
171 | out_be32(&mpc52xx_wdt->count, 0x000000ff); | ||
172 | out_be32(&mpc52xx_wdt->mode, 0x00009004); | ||
173 | } else | ||
174 | printk("mpc52xx_restart: Can't access wdt. " | ||
175 | "Restart impossible, system halted.\n"); | ||
176 | |||
177 | while (1); | ||
178 | } | ||