Blackfin arch: merge adeos blackfin part to arch/blackfin/
[linux-3.10.git] / arch / blackfin / mach-common / interrupt.S
index 1d5ba5e..c1bdd1e 100644 (file)
  */
 
 #include <asm/blackfin.h>
-#include <asm/mach/irq.h>
-#include <linux/autoconf.h>
+#include <mach/irq.h>
 #include <linux/linkage.h>
 #include <asm/entry.h>
 #include <asm/asm-offsets.h>
 #include <asm/trace.h>
+#include <asm/traps.h>
+#include <asm/thread_info.h>
 
-#include <asm/mach-common/context.S>
+#include <asm/context.S>
+
+.extern _ret_from_exception
 
 #ifdef CONFIG_I_ENTRY_L1
 .section .l1.text
@@ -118,16 +121,23 @@ __common_int_entry:
 
 #if ANOMALY_05000283 || ANOMALY_05000315
        cc = r7 == r7;
-       p5.h = 0xffc0;
-       p5.l = 0x0014;
+       p5.h = HI(CHIPID);
+       p5.l = LO(CHIPID);
        if cc jump 1f;
        r7.l = W[p5];
 1:
 #endif
        r1 =  sp;
        SP += -12;
+#ifdef CONFIG_IPIPE
+       call ___ipipe_grab_irq
+       SP += 12;
+       cc = r0 == 0;
+       if cc jump .Lcommon_restore_context;
+#else /* CONFIG_IPIPE */
        call _do_irq;
        SP += 12;
+#endif /* CONFIG_IPIPE */
        call _return_from_int;
 .Lcommon_restore_context:
        RESTORE_CONTEXT
@@ -135,26 +145,28 @@ __common_int_entry:
 
 /* interrupt routine for ivhw - 5 */
 ENTRY(_evt_ivhw)
-       SAVE_CONTEXT
+       SAVE_ALL_SYS
 #ifdef CONFIG_FRAME_POINTER
        fp = 0;
 #endif
-#if ANOMALY_05000283
+
+#if ANOMALY_05000283 || ANOMALY_05000315
        cc = r7 == r7;
-       p5.h = 0xffc0;
-       p5.l = 0x0014;
+       p5.h = HI(CHIPID);
+       p5.l = LO(CHIPID);
        if cc jump 1f;
        r7.l = W[p5];
 1:
 #endif
 
-       trace_buffer_stop(p0, r0);
-
-       r0 = IRQ_HWERR;
-       r1 = sp;
+       # We are going to dump something out, so make sure we print IPEND properly
+       p2.l = lo(IPEND);
+       p2.h = hi(IPEND);
+       r0 = [p2];
+       [sp + PT_IPEND] = r0;
 
 #ifdef CONFIG_HARDWARE_PM
-       r7 = SEQSTAT;
+       r7 = [sp + PT_SEQSTAT];
        r7 = r7 >>> 0xe;
        r6 = 0x1F;
        r7 = r7 & r6;
@@ -163,41 +175,54 @@ ENTRY(_evt_ivhw)
        if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */
 #endif
 
+       /* set the EXCAUSE to HWERR for trap_c */
+       r0 = [sp + PT_SEQSTAT];
+       R1.L = LO(VEC_HWERR);
+       R1.H = HI(VEC_HWERR);
+       R0 = R0 | R1;
+       [sp + PT_SEQSTAT] = R0;
+
+       r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
        SP += -12;
-       call _irq_panic;
+       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;
+
 #ifdef CONFIG_HARDWARE_PM
 .Lcall_do_ovf:
 
+       R0 = SP;
        SP += -12;
        call _pm_overflow;
        SP += 12;
 
-       jump .Lcommon_restore_context;
+       jump .Lcommon_restore_all_sys;
 #endif
 
-/* interrupt routine for evt2 - 2.  This is NMI.  */
-ENTRY(_evt_evt2)
-       SAVE_CONTEXT
-#ifdef CONFIG_FRAME_POINTER
-       fp = 0;
-#endif
-#if ANOMALY_05000283
-       cc = r7 == r7;
-       p5.h = 0xffc0;
-       p5.l = 0x0014;
-       if cc jump 1f;
-       r7.l = W[p5];
-1:
-#endif
-       r0 = IRQ_NMI;
-       r1 =  sp;
-       SP += -12;
-       call _asm_do_IRQ;
-       SP += 12;
-       RESTORE_CONTEXT
+ENDPROC(_evt_ivhw)
+
+/* Interrupt routine for evt2 (NMI).
+ * We don't actually use this, so just return.
+ * For inner circle type details, please see:
+ * http://docs.blackfin.uclinux.org/doku.php?id=linux:nmi
+ */
+ENTRY(_evt_nmi)
+.weak _evt_nmi
        rtn;
+ENDPROC(_evt_nmi)
 
 /* interrupt routine for core timer - 6 */
 ENTRY(_evt_timer)
@@ -229,3 +254,56 @@ ENTRY(_evt_system_call)
        call _system_call;
        jump .Lcommon_restore_context;
 ENDPROC(_evt_system_call)
+
+#ifdef CONFIG_IPIPE
+ENTRY(___ipipe_call_irqtail)
+       r0.l = 1f;
+       r0.h = 1f;
+       reti = r0;
+       rti;
+1:
+       [--sp] = rets;
+       [--sp] = ( r7:4, p5:3 );
+       p0.l = ___ipipe_irq_tail_hook;
+       p0.h = ___ipipe_irq_tail_hook;
+       p0 = [p0];
+       sp += -12;
+       call (p0);
+       sp += 12;
+       ( r7:4, p5:3 ) = [sp++];
+       rets = [sp++];
+
+       [--sp] = reti;
+       reti = [sp++];          /* IRQs are off. */
+       r0.h = 3f;
+       r0.l = 3f;
+       p0.l = lo(EVT14);
+       p0.h = hi(EVT14);
+       [p0] = r0;
+       csync;
+       r0 = 0x401f;
+       sti r0;
+       raise 14;
+       [--sp] = reti;          /* IRQs on. */
+2:
+       jump 2b;                /* Likely paranoid. */
+3:
+       sp += 4;                /* Discard saved RETI */
+       r0.h = _evt14_softirq;
+       r0.l = _evt14_softirq;
+       p0.l = lo(EVT14);
+       p0.h = hi(EVT14);
+       [p0] = r0;
+       csync;
+       p0.l = _bfin_irq_flags;
+       p0.h = _bfin_irq_flags;
+       r0 = [p0];
+       sti r0;
+#if 0 /* FIXME: this actually raises scheduling latencies */
+       /* Reenable interrupts */
+       [--sp] = reti;
+       r0 = [sp++];
+#endif
+       rts;
+ENDPROC(___ipipe_call_irqtail)
+#endif /* CONFIG_IPIPE */