[PATCH] ppc32: Add soft reset to MPC834x
authorKumar Gala <galak@freescale.com>
Sat, 28 May 2005 22:52:15 +0000 (15:52 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 28 May 2005 23:46:16 +0000 (16:46 -0700)
This change allows mpc83xx_restart to issue a software reset.

Signed-off-by: Randy Vinson <rvinson@mvista.com>
Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/ppc/platforms/83xx/mpc834x_sys.h
arch/ppc/syslib/ppc83xx_setup.c

index 49db0f4c847e222ac8431a5c6d7e5a59753ac0ae..a2f6e49d71512946ca5e89e2b7d7ca80fec0f8de 100644 (file)
 #define BCSR_PHYS_ADDR         ((uint)0xf8000000)
 #define BCSR_SIZE              ((uint)(32 * 1024))
 
+#define BCSR_MISC_REG2_OFF     0x07
+#define BCSR_MISC_REG2_PORESET 0x01
+
+#define BCSR_MISC_REG3_OFF     0x08
+#define BCSR_MISC_REG3_CNFLOCK 0x80
+
 #ifdef CONFIG_PCI
 /* PCI interrupt controller */
 #define PIRQA        MPC83xx_IRQ_IRQ4
index c28f9d679484f348e18c5409141983be5a7fcfe6..843cf8873e60f35376b80e2cda72839ee99fb35a 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/mmu.h>
 #include <asm/ppc_sys.h>
 #include <asm/kgdb.h>
+#include <asm/delay.h>
 
 #include <syslib/ppc83xx_setup.h>
 
@@ -117,7 +118,34 @@ mpc83xx_early_serial_map(void)
 void
 mpc83xx_restart(char *cmd)
 {
+       volatile unsigned char __iomem *reg;
+       unsigned char tmp;
+
+       reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
+
        local_irq_disable();
+
+       /*
+        * Unlock the BCSR bits so a PRST will update the contents.
+        * Otherwise the reset asserts but doesn't clear.
+        */
+       tmp = in_8(reg + BCSR_MISC_REG3_OFF);
+       tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
+       out_8(reg + BCSR_MISC_REG3_OFF, tmp);
+
+       /*
+        * Trigger a reset via a low->high transition of the
+        * PORESET bit.
+        */
+       tmp = in_8(reg + BCSR_MISC_REG2_OFF);
+       tmp &= ~BCSR_MISC_REG2_PORESET;
+       out_8(reg + BCSR_MISC_REG2_OFF, tmp);
+
+       udelay(1);
+
+       tmp |= BCSR_MISC_REG2_PORESET;
+       out_8(reg + BCSR_MISC_REG2_OFF, tmp);
+
        for(;;);
 }