Blackfin: make EVT3->EVT5 lowering more robust wrt IPEND[4]

We handle many exceptions at EVT5 (hardware error level) so that we can
catch exceptions in our exception handling code.  Today - if the global
interrupt enable bit (IPEND[4]) is set (interrupts disabled) our trap
handling code goes into a infinite loop, since we need interrupts to be
on to defer things to EVT5.

Normal kernel code should not trigger this for any reason as IPEND[4] gets
cleared early (when doing an interrupt context save) and the kernel stack
there should be sane (or something much worse is happening in the system).
But there have been a few times where this has happened, so this change
makes sure we dump a proper crash message even when things have gone south.

Signed-off-by: Robin Getz <robin.getz@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index b5df945..8ad4f2c 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -145,6 +145,7 @@
 	DEFINE(PDA_EXBUF, offsetof(struct blackfin_pda, ex_buf));
 	DEFINE(PDA_EXIMASK, offsetof(struct blackfin_pda, ex_imask));
 	DEFINE(PDA_EXSTACK, offsetof(struct blackfin_pda, ex_stack));
+	DEFINE(PDA_EXIPEND, offsetof(struct blackfin_pda, ex_ipend));
 #ifdef ANOMALY_05000261
 	DEFINE(PDA_LFRETX, offsetof(struct blackfin_pda, last_cplb_fault_retx));
 #endif
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index bf2b2d1..fccf741 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -267,11 +267,6 @@
 	 * double faults if the stack has become corrupt
 	 */
 
-#ifndef CONFIG_KGDB
-	/* IPEND is skipped if KGDB isn't enabled (see entry code) */
-	fp->ipend = bfin_read_IPEND();
-#endif
-
 	/* trap_c() will be called for exceptions. During exceptions
 	 * processing, the pc value should be set with retx value.
 	 * With this change we can cleanup some code in signal.c- TODO
@@ -1116,10 +1111,16 @@
 
 	verbose_printk(KERN_NOTICE "%s", linux_banner);
 
-	verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n",
-		       print_tainted());
-	verbose_printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",
-		       (long)fp->seqstat, fp->ipend, fp->syscfg);
+	verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted());
+	verbose_printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  IMASK: %04lx  SYSCFG: %04lx\n",
+		(long)fp->seqstat, fp->ipend, cpu_pda[smp_processor_id()].ex_imask, fp->syscfg);
+	if (fp->ipend & EVT_IRPTEN)
+		verbose_printk(KERN_NOTICE "  Global Interrupts Disabled (IPEND[4])\n");
+	if (!(cpu_pda[smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 |
+			EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR)))
+		verbose_printk(KERN_NOTICE "  Peripheral interrupts masked off\n");
+	if (!(cpu_pda[smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14)))
+		verbose_printk(KERN_NOTICE "  Kernel interrupts masked off\n");
 	if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) {
 		verbose_printk(KERN_NOTICE "  HWERRCAUSE: 0x%lx\n",
 			(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);