aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.h6
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.c28
2 files changed, 34 insertions, 0 deletions
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
index 49db0f4c847..a2f6e49d715 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -28,6 +28,12 @@
#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
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
index c28f9d67948..843cf8873e6 100644
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -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(;;);
}