sh: Fix bogus regs pointer in do_IRQ().
authorPaul Mundt <lethal@linux-sh.org>
Wed, 14 Mar 2007 04:03:35 +0000 (13:03 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 14 Mar 2007 04:03:35 +0000 (13:03 +0900)
SH-3 and SH-4 were trampling the register, and SH-2 wasn't even
setting it in the first place. This ended up with some rather
broken behaviour in the sysrq show_regs().

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/kernel/cpu/sh2/entry.S
arch/sh/kernel/cpu/sh3/entry.S
arch/sh/kernel/irq.c
include/asm-sh/irq.h

index 7f7d292f36ec12d49aebaf956cbeafe4db2369bb..c16dc8fec489655ccf106612ab77a0adf6c3b7c0 100644 (file)
@@ -165,6 +165,7 @@ ENTRY(exception_handler)
 
 interrupt_entry:
        mov     r9,r4
+       mov     r15,r5
        mov.l   6f,r9
        mov.l   7f,r8
        jmp     @r8
index c19205b0f2c001d2ce1cd73c7dba7674890d102f..f3e827f29a46b298eb6a31561fe80dfe09340460 100644 (file)
@@ -514,13 +514,16 @@ skip_save:
 
 interrupt_exception:
        mov.l   1f, r9
+       mov.l   2f, r4
+       mov.l   @r4, r4
        jmp     @r9
-        nop
+        mov    r15, r5
        rts
         nop
 
        .align 2
 1:     .long   do_IRQ
+2:     .long   INTEVT
 
        .align  2
 ENTRY(exception_none)
index 67be2b6e8cd1657cdf657d50259806572c236580..9bdd8a00cd4a3a8b5dffb10a0911bdff37f13079 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
-#include <linux/io.h>
 #include <linux/irq.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
@@ -82,13 +81,9 @@ static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
 static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
 #endif
 
-asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
-                     unsigned long r6, unsigned long r7,
-                     struct pt_regs __regs)
+asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
-       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        struct pt_regs *old_regs = set_irq_regs(regs);
-       int irq;
 #ifdef CONFIG_4KSTACKS
        union irq_ctx *curctx, *irqctx;
 #endif
@@ -111,13 +106,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
        }
 #endif
 
-#ifdef CONFIG_CPU_HAS_INTEVT
-       irq = evt2irq(ctrl_inl(INTEVT));
-#else
-       irq = r4;
-#endif
-
-       irq = irq_demux(irq);
+       irq = irq_demux(evt2irq(irq));
 
 #ifdef CONFIG_4KSTACKS
        curctx = (union irq_ctx *)current_thread_info();
index 8ccf7ae593efaf871b0d8e7ec04e2625ae91eb72..afe188f0ad5f444ee60e7356ec650de87f6216fd 100644 (file)
 /*
  * Convert back and forth between INTEVT and IRQ values.
  */
+#ifdef CONFIG_CPU_HAS_INTEVT
 #define evt2irq(evt)           (((evt) >> 5) - 16)
 #define irq2evt(irq)           (((irq) + 16) << 5)
+#else
+#define evt2irq(evt)           (evt)
+#define irq2evt(irq)           (irq)
+#endif
 
 /*
  * Simple Mask Register Support