Blackfin arch: Fix bug - HW Errors never recover on BF548
authorRobin Getz <rgetz@blackfin.uclinux.org>
Thu, 9 Oct 2008 09:06:32 +0000 (17:06 +0800)
committerBryan Wu <cooloney@kernel.org>
Thu, 9 Oct 2008 09:06:32 +0000 (17:06 +0800)
The kernel does not properly clear the EBIU Error Master (EBIU_ERRMST) Register
on BF548, which causes the kernel to panic.

We need to make sure that we clear the EBIU_ERRMST (necessary on BF54x)

Signed-off-by: Robin Getz <rgetz@blackfin.uclinux.org>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
arch/blackfin/kernel/traps.c
arch/blackfin/mach-common/interrupt.S

index 1a3c4daf557a8f10bc79051e68be1ab638a6b7d9..709c247b70169f9a79dd0b68db11e2de3c5353ba 100644 (file)
@@ -1025,8 +1025,19 @@ void show_regs(struct pt_regs *fp)
        printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted());
        printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",
                (long)fp->seqstat, fp->ipend, fp->syscfg);
-       printk(KERN_NOTICE "  HWERRCAUSE: 0x%lx\n",
-               (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
+       if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) {
+               printk(KERN_NOTICE "  HWERRCAUSE: 0x%lx\n",
+                       (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
+#ifdef EBIU_ERRMST
+               /* If the error was from the EBIU, print it out */
+               if (bfin_read_EBIU_ERRMST() & CORE_ERROR) {
+                       printk(KERN_NOTICE "  EBIU Error Reason  : 0x%04x\n",
+                               bfin_read_EBIU_ERRMST());
+                       printk(KERN_NOTICE "  EBIU Error Address : 0x%08x\n",
+                               bfin_read_EBIU_ERRADD());
+               }
+#endif
+       }
        printk(KERN_NOTICE "  EXCAUSE   : 0x%lx\n",
                fp->seqstat & SEQSTAT_EXCAUSE);
        for (i = 6; i <= 15 ; i++) {
index 647f0f5229106858fa89c50954c0393776ad2a94..4a2ec7a9675a95698638d6b942c59c6de6fc6cfc 100644 (file)
@@ -179,7 +179,16 @@ ENTRY(_evt_ivhw)
        call _trap_c;
        SP += 12;
 
+#ifdef EBIU_ERRMST
+       /* make sure EBIU_ERRMST is clear */
+       p0.l = LO(EBIU_ERRMST);
+       p0.h = HI(EBIU_ERRMST);
+       r0.l = (CORE_ERROR | CORE_MERROR);
+       w[p0] = r0.l;
+#endif
+
        call _ret_from_exception;
+
 .Lcommon_restore_all_sys:
        RESTORE_ALL_SYS
        rti;