diff options
Diffstat (limited to 'arch/blackfin/mach-common/interrupt.S')
-rw-r--r-- | arch/blackfin/mach-common/interrupt.S | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index 2604b532897c..c1bdd1edc8eb 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S @@ -129,8 +129,15 @@ __common_int_entry: #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 @@ -247,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 */ |