summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2007-01-26 09:37:11 +0300
committerKumar Gala <galak@kernel.crashing.org>2007-01-26 09:37:11 +0300
commitc75f902b93724ab9ba161f7dfab0fd09c7a8854d (patch)
treee64be7c00540aece57b7ffe2e169c5fb7f32ad85
parent4d52719a767455d319263d598e0f59e027895e00 (diff)
downloadlinux-c75f902b93724ab9ba161f7dfab0fd09c7a8854d.tar.xz
[POWERPC] 83xx: Don't call ioremap in the reset function
It's possibly that we get an reset requestion when interrupts are disabled. (For example an oops in an interrupt handler). Therefor, we can't call ioremap in the reset function. Moving the ioremap of the registers we need access to an arch_initcall helps the problem. However we still have a window between boot and the arch_initcall in which the register pointer will not be setup and thus we spin if the reset function is called. If one needs to ensure even this case is covered, look at use of the watchdog provided on 83xx to reset the processor. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r--arch/powerpc/platforms/83xx/misc.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c
index f0c6df61faa9..f01806c940e1 100644
--- a/arch/powerpc/platforms/83xx/misc.c
+++ b/arch/powerpc/platforms/83xx/misc.c
@@ -18,23 +18,36 @@
#include "mpc83xx.h"
+static __be32 __iomem *restart_reg_base;
+
+static int __init mpc83xx_restart_init(void)
+{
+ /* map reset restart_reg_baseister space */
+ restart_reg_base = ioremap(get_immrbase() + 0x900, 0xff);
+
+ return 0;
+}
+
+arch_initcall(mpc83xx_restart_init);
+
void mpc83xx_restart(char *cmd)
{
#define RST_OFFSET 0x00000900
#define RST_PROT_REG 0x00000018
#define RST_CTRL_REG 0x0000001c
- __be32 __iomem *reg;
-
- /* map reset register space */
- reg = ioremap(get_immrbase() + 0x900, 0xff);
local_irq_disable();
- /* enable software reset "RSTE" */
- out_be32(reg + (RST_PROT_REG >> 2), 0x52535445);
+ if (restart_reg_base) {
+ /* enable software reset "RSTE" */
+ out_be32(restart_reg_base + (RST_PROT_REG >> 2), 0x52535445);
+
+ /* set software hard reset */
+ out_be32(restart_reg_base + (RST_CTRL_REG >> 2), 0x2);
+ } else {
+ printk (KERN_EMERG "Error: Restart registers not mapped, spinning!\n");
+ }
- /* set software hard reset */
- out_be32(reg + (RST_CTRL_REG >> 2), 0x2);
for (;;) ;
}