Make sure that RA on top of interrupt stack is an address of ret_from_irq,
so that dump_stack etc. can trace info interrupted context.
Also this patch fixes except_vec_vi_handler and __smtc_ipi_vector which
seems broken.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
 handle_it:
                LONG_L  s0, TI_REGS($28)
                LONG_S  sp, TI_REGS($28)
-               jal     do_IRQ
-               LONG_S  s0, TI_REGS($28)
-
-               j       ret_from_irq
+               PTR_LA  ra, ret_from_irq
+               j       do_IRQ
                 nop
 
 #ifdef CONFIG_32BIT
 #endif
 
 spurious:
-               jal     spurious_interrupt
-                nop
-               j       ret_from_irq
+               PTR_LA  ra, _ret_from_irq
+               j       spurious_interrupt
                 nop
                END(plat_irq_dispatch)
 
 
 #include <asm/mipsmtregs.h>
 #endif
 
-#ifdef CONFIG_PREEMPT
-       .macro  preempt_stop
-       .endm
-#else
+#ifndef CONFIG_PREEMPT
        .macro  preempt_stop
        local_irq_disable
        .endm
 
        .text
        .align  5
+FEXPORT(ret_from_irq)
+       LONG_S  s0, TI_REGS($28)
+#ifdef CONFIG_PREEMPT
+FEXPORT(ret_from_exception)
+#else
+       b       _ret_from_irq
 FEXPORT(ret_from_exception)
        preempt_stop
-FEXPORT(ret_from_irq)
+#endif
+FEXPORT(_ret_from_irq)
        LONG_L  t0, PT_STATUS(sp)               # returning to kernel mode?
        andi    t0, t0, KU_USER
        beqz    t0, resume_kernel
 
 
        LONG_L  s0, TI_REGS($28)
        LONG_S  sp, TI_REGS($28)
-       jal     plat_irq_dispatch
-       LONG_S  s0, TI_REGS($28)
-       j       ret_from_irq
+       PTR_LA  ra, ret_from_irq
+       j       plat_irq_dispatch
        END(handle_int)
 
        __INIT
 
        LONG_L  s0, TI_REGS($28)
        LONG_S  sp, TI_REGS($28)
-       jalr    v0
-       LONG_S  s0, TI_REGS($28)
        PTR_LA  ra, ret_from_irq
+       jr      v0
        END(except_vec_vi_handler)
 
 /*
 
        SAVE_ALL
        CLI
        TRACE_IRQS_OFF
-       move    a0,sp
        /* Function to be invoked passed stack pad slot 5 */
        lw      t0,PT_PADSLOT5(sp)
        /* Argument from sender passed in stack pad slot 4 */
-       lw      a1,PT_PADSLOT4(sp)
-       jalr    t0
-       nop
-       j       ret_from_irq
-       nop
+       lw      a0,PT_PADSLOT4(sp)
+       PTR_LA  ra, _ret_from_irq
+       jr      t0
 
 /*
  * Called from idle loop to provoke processing of queued IPIs