[MIPS] Rewrite all the assembler interrupt handlers to C.
authorRalf Baechle <ralf@linux-mips.org>
Mon, 3 Apr 2006 16:56:36 +0000 (17:56 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Wed, 19 Apr 2006 02:14:21 +0000 (04:14 +0200)
Saves like 1,600 lines of code, is way easier to debug, compilers
frequently do a better job than the cut and paste type of handlers many
boards had.  And finally having all the stuff done in a single place
also means alot of bug potencial for the MT ASE is gone.

The only surviving handler in assembler is the DECstation one; I hope
Maciej will rewrite it.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
100 files changed:
arch/mips/au1000/common/Makefile
arch/mips/au1000/common/int-handler.S [deleted file]
arch/mips/au1000/common/irq.c
arch/mips/cobalt/Makefile
arch/mips/cobalt/int-handler.S [deleted file]
arch/mips/cobalt/irq.c
arch/mips/ddb5xxx/ddb5074/Makefile
arch/mips/ddb5xxx/ddb5074/int-handler.S [deleted file]
arch/mips/ddb5xxx/ddb5074/irq.c
arch/mips/ddb5xxx/ddb5476/Makefile
arch/mips/ddb5xxx/ddb5476/int-handler.S [deleted file]
arch/mips/ddb5xxx/ddb5476/irq.c
arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
arch/mips/ddb5xxx/ddb5477/Makefile
arch/mips/ddb5xxx/ddb5477/int-handler.S [deleted file]
arch/mips/ddb5xxx/ddb5477/irq.c
arch/mips/dec/int-handler.S
arch/mips/dec/setup.c
arch/mips/galileo-boards/ev96100/Makefile
arch/mips/galileo-boards/ev96100/int-handler.S [deleted file]
arch/mips/galileo-boards/ev96100/irq.c
arch/mips/gt64120/ev64120/Makefile
arch/mips/gt64120/ev64120/int-handler.S [deleted file]
arch/mips/gt64120/ev64120/irq.c
arch/mips/gt64120/momenco_ocelot/Makefile
arch/mips/gt64120/momenco_ocelot/int-handler.S [deleted file]
arch/mips/gt64120/momenco_ocelot/irq.c
arch/mips/ite-boards/generic/Makefile
arch/mips/ite-boards/generic/int-handler.S [deleted file]
arch/mips/ite-boards/generic/irq.c
arch/mips/jazz/Makefile
arch/mips/jazz/int-handler.S [deleted file]
arch/mips/jazz/irq.c
arch/mips/jmr3927/rbhma3100/Makefile
arch/mips/jmr3927/rbhma3100/int-handler.S [deleted file]
arch/mips/jmr3927/rbhma3100/irq.c
arch/mips/kernel/genex.S
arch/mips/kernel/traps.c
arch/mips/lasat/Makefile
arch/mips/lasat/interrupt.c
arch/mips/lasat/lasatIRQ.S [deleted file]
arch/mips/mips-boards/atlas/Makefile
arch/mips/mips-boards/atlas/atlas-irq.S [deleted file]
arch/mips/mips-boards/atlas/atlas_int.c
arch/mips/mips-boards/malta/Makefile
arch/mips/mips-boards/malta/malta-irq.S [deleted file]
arch/mips/mips-boards/malta/malta_int.c
arch/mips/mips-boards/sead/Makefile
arch/mips/mips-boards/sead/sead-irq.S [deleted file]
arch/mips/mips-boards/sead/sead_int.c
arch/mips/mips-boards/sim/sim_int.c
arch/mips/momentum/jaguar_atx/Makefile
arch/mips/momentum/jaguar_atx/int-handler.S [deleted file]
arch/mips/momentum/jaguar_atx/irq.c
arch/mips/momentum/ocelot_3/Makefile
arch/mips/momentum/ocelot_3/int-handler.S [deleted file]
arch/mips/momentum/ocelot_3/irq.c
arch/mips/momentum/ocelot_c/Makefile
arch/mips/momentum/ocelot_c/int-handler.S [deleted file]
arch/mips/momentum/ocelot_c/irq.c
arch/mips/momentum/ocelot_g/Makefile
arch/mips/momentum/ocelot_g/int-handler.S [deleted file]
arch/mips/momentum/ocelot_g/irq.c
arch/mips/philips/pnx8550/common/Makefile
arch/mips/philips/pnx8550/common/int.c
arch/mips/philips/pnx8550/common/mipsIRQ.S [deleted file]
arch/mips/pmc-sierra/yosemite/Makefile
arch/mips/pmc-sierra/yosemite/irq-handler.S [deleted file]
arch/mips/pmc-sierra/yosemite/irq.c
arch/mips/qemu/Makefile
arch/mips/qemu/q-int.S [deleted file]
arch/mips/qemu/q-irq.c
arch/mips/sgi-ip22/Makefile
arch/mips/sgi-ip22/ip22-int.c
arch/mips/sgi-ip22/ip22-irq.S [deleted file]
arch/mips/sgi-ip27/Makefile
arch/mips/sgi-ip27/TODO
arch/mips/sgi-ip27/ip27-irq-glue.S [deleted file]
arch/mips/sgi-ip27/ip27-irq.c
arch/mips/sgi-ip32/Makefile
arch/mips/sgi-ip32/ip32-irq-glue.S [deleted file]
arch/mips/sgi-ip32/ip32-irq.c
arch/mips/sibyte/bcm1480/Makefile
arch/mips/sibyte/bcm1480/irq.c
arch/mips/sibyte/bcm1480/irq_handler.S [deleted file]
arch/mips/sibyte/sb1250/Makefile
arch/mips/sibyte/sb1250/irq.c
arch/mips/sibyte/sb1250/irq_handler.S [deleted file]
arch/mips/sni/Makefile
arch/mips/sni/int-handler.S [deleted file]
arch/mips/sni/irq.c
arch/mips/tx4927/common/Makefile
arch/mips/tx4927/common/tx4927_irq.c
arch/mips/tx4927/common/tx4927_irq_handler.S [deleted file]
arch/mips/tx4938/common/Makefile
arch/mips/tx4938/common/irq.c
arch/mips/tx4938/common/irq_handler.S [deleted file]
arch/mips/vr41xx/common/Makefile
arch/mips/vr41xx/common/int-handler.S [deleted file]
arch/mips/vr41xx/common/irq.c

index a1edfd1..bf682f5 100644 (file)
@@ -6,7 +6,7 @@
 # Makefile for the Alchemy Au1000 CPU, generic files.
 #
 
-obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \
+obj-y += prom.o irq.o puts.o time.o reset.o \
        au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
        sleeper.o cputable.o dma.o dbdma.o gpio.o
 
diff --git a/arch/mips/au1000/common/int-handler.S b/arch/mips/au1000/common/int-handler.S
deleted file mode 100644 (file)
index 65baa8a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: ppopov@mvista.com
- *
- * Interrupt dispatcher for Au1000 boards.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under  the terms of the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-       .text
-       .set    macro
-       .set    noat
-       .align  5
-
-NESTED(au1000_IRQ, PT_SIZE, sp)
-       SAVE_ALL
-       CLI                             # Important: mark KERNEL mode !
-
-       mfc0    t0,CP0_CAUSE            # get pending interrupts
-       mfc0    t1,CP0_STATUS           # get enabled interrupts
-       and     t0,t1                   # isolate allowed ones
-
-       andi    t0,0xff00               # isolate pending bits
-       beqz    t0, 3f                  # spurious interrupt
-
-       andi    a0, t0, CAUSEF_IP7
-       beq     a0, zero, 1f
-       move    a0, sp
-       jal     mips_timer_interrupt
-       j       ret_from_irq
-
-1:
-       andi    a0, t0, CAUSEF_IP2      # Interrupt Controller 0, Request 0
-       beq     a0, zero, 2f
-       move    a0,sp
-       jal     intc0_req0_irqdispatch
-       j       ret_from_irq
-2:
-       andi    a0, t0, CAUSEF_IP3      # Interrupt Controller 0, Request 1
-       beq     a0, zero, 3f
-       move    a0,sp
-       jal     intc0_req1_irqdispatch
-       j       ret_from_irq
-3:
-       andi    a0, t0, CAUSEF_IP4      # Interrupt Controller 1, Request 0
-       beq     a0, zero, 4f
-       move    a0,sp
-       jal     intc1_req0_irqdispatch
-       j       ret_from_irq
-4:
-       andi    a0, t0, CAUSEF_IP5      # Interrupt Controller 1, Request 1
-       beq     a0, zero, 5f
-       move    a0, sp
-       jal     intc1_req1_irqdispatch
-       j       ret_from_irq
-
-5:
-       move    a0, sp
-       jal     spurious_interrupt
-       j       ret_from_irq
-END(au1000_IRQ)
index 1339a09..da61de7 100644 (file)
@@ -66,7 +66,6 @@
 #define EXT_INTC1_REQ1 5 /* IP 5 */
 #define MIPS_TIMER_IP  7 /* IP 7 */
 
-extern asmlinkage void au1000_IRQ(void);
 extern void set_debug_traps(void);
 extern irq_cpustat_t irq_stat [NR_CPUS];
 
@@ -446,7 +445,6 @@ void __init arch_init_irq(void)
        extern int au1xxx_ic0_nr_irqs;
 
        cp0_status = read_c0_status();
-       set_except_vector(0, au1000_IRQ);
 
        /* Initialize interrupt controllers to a safe state.
        */
@@ -661,3 +659,21 @@ restore_au1xxx_intctl(void)
        au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync();
 }
 #endif /* CONFIG_PM */
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+       if (pending & CAUSEF_IP7)
+               mips_timer_interrupt(regs);
+       else if (pending & CAUSEF_IP2)
+               intc0_req0_irqdispatch(regs);
+       else if (pending & CAUSEF_IP3)
+               intc0_req1_irqdispatch(regs);
+       else if (pending & CAUSEF_IP4)
+               intc1_req0_irqdispatch(regs);
+       else if (pending  & CAUSEF_IP5)
+               intc1_req1_irqdispatch(regs);
+       else
+               spurious_interrupt(regs);
+}
index 720e757..225ac8f 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the Cobalt micro systems family specific parts of the kernel
 #
 
-obj-y   := irq.o int-handler.o reset.o setup.o
+obj-y   := irq.o reset.o setup.o
 
 obj-$(CONFIG_EARLY_PRINTK)     += console.o
 
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S
deleted file mode 100644 (file)
index e75d5e3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
- * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/mach-cobalt/cobalt.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-               .text
-               .align  5
-               NESTED(cobalt_handle_int, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-
-               PTR_LA  ra, ret_from_irq
-               move    a0, sp
-               j       cobalt_irq
-
-               END(cobalt_handle_int)
index f9a1088..0b75f4f 100644 (file)
@@ -20,8 +20,6 @@
 
 #include <asm/mach-cobalt/cobalt.h>
 
-extern void cobalt_handle_int(void);
-
 /*
  * We have two types of interrupts that we handle, ones that come in through
  * the CPU interrupt lines, and ones that come in on the via chip. The CPU
@@ -79,7 +77,7 @@ static inline void via_pic_irq(struct pt_regs *regs)
                do_IRQ(irq, regs);
 }
 
-asmlinkage void cobalt_irq(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 {
        unsigned pending;
 
@@ -122,8 +120,6 @@ void __init arch_init_irq(void)
         */
        GALILEO_OUTL(0, GT_INTRMASK_OFS);
 
-       set_except_vector(0, cobalt_handle_int);
-
        init_i8259_irqs();                              /*  0 ... 15 */
        mips_cpu_irq_init(COBALT_CPU_IRQ);              /* 16 ... 23 */
 
index 488206b..304c021 100644 (file)
@@ -3,6 +3,6 @@
 # under Linux.
 #
 
-obj-y                  += setup.o irq.o int-handler.o nile4_pic.o
+obj-y                  += setup.o irq.o nile4_pic.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ddb5xxx/ddb5074/int-handler.S b/arch/mips/ddb5xxx/ddb5074/int-handler.S
deleted file mode 100644 (file)
index a786441..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *  arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
- *
- *  Based on arch/mips/sgi/kernel/indyIRQ.S
- *
- *  Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
- *                     Sony Software Development Center Europe (SDCE), Brussels
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/* A lot of complication here is taken away because:
- *
- * 1) We handle one interrupt and return, sitting in a loop and moving across
- *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
- *    common case is one pending IRQ so optimize in that direction.
- *
- * 2) We need not check against bits in the status register IRQ mask, that
- *    would make this routine slow as hell.
- *
- * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
- *    between like BSD spl() brain-damage.
- *
- * Furthermore, the IRQs on the INDY look basically (barring software IRQs
- * which we don't use at all) like:
- *
- *     MIPS IRQ        Source
- *      --------        ------
- *             0       Software (ignored)
- *             1        Software (ignored)
- *             2        Local IRQ level zero
- *             3        Local IRQ level one
- *             4        8254 Timer zero
- *             5        8254 Timer one
- *             6        Bus Error
- *             7        R4k timer (what we use)
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ----     R4k Timer
- *                  Local IRQ zero
- *                  Local IRQ one
- *                  Bus Error
- *                  8254 Timer zero
- * Lowest  ----     8254 Timer one
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
-       .text
-       .set    noreorder
-       .set    noat
-       .align  5
-       NESTED(ddbIRQ, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-       .set    at
-       mfc0    s0, CP0_CAUSE           # get irq mask
-
-#if 1
-       mfc0    t2,CP0_STATUS           # get enabled interrupts
-       and     s0,t2                   # isolate allowed ones
-#endif
-       /* First we check for r4k counter/timer IRQ. */
-       andi    a0, s0, CAUSEF_IP2      # delay slot, check local level zero
-       beq     a0, zero, 1f
-        andi   a0, s0, CAUSEF_IP3      # delay slot, check local level one
-
-       /* Wheee, local level zero interrupt. */
-       jal     ddb_local0_irqdispatch
-        move   a0, sp                  # delay slot
-
-       j       ret_from_irq
-        nop                            # delay slot
-
-1:
-       beq     a0, zero, 1f
-        andi   a0, s0, CAUSEF_IP6      # delay slot, check bus error
-
-       /* Wheee, local level one interrupt. */
-       move    a0, sp
-       jal     ddb_local1_irqdispatch
-        nop
-
-       j       ret_from_irq
-        nop
-
-1:
-       beq     a0, zero, 1f
-        nop
-
-       /* Wheee, an asynchronous bus error... */
-       move    a0, sp
-       jal     ddb_buserror_irq
-        nop
-
-       j       ret_from_irq
-        nop
-
-1:
-       /* Here by mistake?  This is possible, what can happen
-        * is that by the time we take the exception the IRQ
-        * pin goes low, so just leave if this is the case.
-        */
-       andi    a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
-       beq     a0, zero, 1f
-
-       /* Must be one of the 8254 timers... */
-       move    a0, sp
-       jal     ddb_8254timer_irq
-        nop
-1:
-       j       ret_from_irq
-        nop
-       END(ddbIRQ)
index 45088a1..60c087b 100644 (file)
@@ -21,8 +21,6 @@
 #include <asm/ddb5xxx/ddb5074.h>
 
 
-extern asmlinkage void ddbIRQ(void);
-
 static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
 
 #define M1543_PNP_CONFIG       0x03f0  /* PnP Config Port */
@@ -90,7 +88,7 @@ static void m1543_irq_setup(void)
 
 }
 
-void ddb_local0_irqdispatch(struct pt_regs *regs)
+static void ddb_local0_irqdispatch(struct pt_regs *regs)
 {
        u32 mask;
        int nile4_irq;
@@ -118,29 +116,41 @@ void ddb_local0_irqdispatch(struct pt_regs *regs)
                }
 }
 
-void ddb_local1_irqdispatch(void)
+static void ddb_local1_irqdispatch(void)
 {
        printk("ddb_local1_irqdispatch called\n");
 }
 
-void ddb_buserror_irq(void)
+static void ddb_buserror_irq(void)
 {
        printk("ddb_buserror_irq called\n");
 }
 
-void ddb_8254timer_irq(void)
+static void ddb_8254timer_irq(void)
 {
        printk("ddb_8254timer_irq called\n");
 }
 
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status();
+
+       if (pending & CAUSEF_IP2)
+               ddb_local0_irqdispatch(regs);
+       else if (pending & CAUSEF_IP3)
+               ddb_local1_irqdispatch();
+       else if (pending & CAUSEF_IP6)
+               ddb_buserror_irq();
+       else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
+               ddb_8254timer_irq();
+}
+
 void __init arch_init_irq(void)
 {
        /* setup cascade interrupts */
        setup_irq(NILE4_IRQ_BASE  + NILE4_INT_INTE, &irq_cascade);
        setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade);
 
-       set_except_vector(0, ddbIRQ);
-
        nile4_irq_setup(NILE4_IRQ_BASE);
        m1543_irq_setup();
        init_i8259_irqs();
index 61eec36..ab0312c 100644 (file)
@@ -3,7 +3,7 @@
 # under Linux.
 #
 
-obj-y                  += setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o
+obj-y                  += setup.o irq.o nile4_pic.o vrc5476_irq.o
 obj-$(CONFIG_KGDB)     += dbg_io.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ddb5xxx/ddb5476/int-handler.S b/arch/mips/ddb5xxx/ddb5476/int-handler.S
deleted file mode 100644 (file)
index 0c2bdae..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * First-level interrupt dispatcher for ddb5476
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-#include <asm/ddb5xxx/ddb5476.h>
-
-/*
- * first level interrupt dispatcher for ocelot board -
- * We check for the timer first, then check PCI ints A and D.
- * Then check for serial IRQ and fall through.
- */
-       .align  5
-       NESTED(ddb5476_handle_int, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-       .set    at
-       .set    noreorder
-       mfc0    t0, CP0_CAUSE
-       mfc0    t2, CP0_STATUS
-
-       and     t0, t2
-
-        andi    t1, t0, STATUSF_IP7     /* cpu timer */
-        bnez    t1, ll_cpu_ip7
-        andi    t1, t0, STATUSF_IP2    /* vrc5476 & i8259 */
-        bnez    t1, ll_cpu_ip2
-        andi    t1, t0, STATUSF_IP3
-        bnez    t1, ll_cpu_ip3
-        andi    t1, t0, STATUSF_IP4
-        bnez    t1, ll_cpu_ip4
-        andi    t1, t0, STATUSF_IP5
-        bnez    t1, ll_cpu_ip5
-        andi    t1, t0, STATUSF_IP6
-        bnez    t1, ll_cpu_ip6
-        andi    t1, t0, STATUSF_IP0     /* software int 0 */
-        bnez    t1, ll_cpu_ip0
-        andi    t1, t0, STATUSF_IP1     /* software int 1 */
-        bnez    t1, ll_cpu_ip1
-        nop
-
-       .set    reorder
-
-       /* wrong alarm or masked ... */
-       // jal  spurious_interrupt
-       // j    ret_from_irq
-       move    a0, sp
-       jal     vrc5476_irq_dispatch
-       j       ret_from_irq
-       nop
-
-       .align  5
-
-ll_cpu_ip0:
-       li      a0, CPU_IRQ_BASE + 0
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
-
-ll_cpu_ip1:
-       li      a0, CPU_IRQ_BASE + 1
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
-
-ll_cpu_ip2:            /* jump to second-level dispatching */
-       move    a0, sp
-       jal     vrc5476_irq_dispatch
-       j       ret_from_irq
-
-ll_cpu_ip3:
-       li      a0, CPU_IRQ_BASE + 3
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
-
-ll_cpu_ip4:
-       li      a0, CPU_IRQ_BASE + 4
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
-
-ll_cpu_ip5:
-       li      a0, CPU_IRQ_BASE + 5
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
-
-ll_cpu_ip6:
-       li      a0, CPU_IRQ_BASE + 6
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
-
-ll_cpu_ip7:
-       li      a0, CPU_IRQ_BASE + 7
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
-
-       END(ddb5476_handle_int)
index 5388b58..7583a1f 100644 (file)
@@ -110,11 +110,36 @@ static void nile4_irq_setup(void)
 static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
 static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL };
 
-extern asmlinkage void ddb5476_handle_int(void);
 extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
 extern void mips_cpu_irq_init(u32 irq_base);
 extern void vrc5476_irq_init(u32 irq_base);
 
+extern void vrc5476_irq_dispatch(struct pt_regs *regs);
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status();
+
+       if (pending & STATUSF_IP7)
+               do_IRQ(CPU_IRQ_BASE + 7, regs);
+       else if (pending & STATUSF_IP2)
+               vrc5476_irq_dispatch(regs);
+       else if (pending & STATUSF_IP3)
+               do_IRQ(CPU_IRQ_BASE + 3, regs);
+       else if (pending & STATUSF_IP4)
+               do_IRQ(CPU_IRQ_BASE + 4, regs);
+       else if (pending & STATUSF_IP5)
+               do_IRQ(CPU_IRQ_BASE + 5, regs);
+       else if (pending & STATUSF_IP6)
+               do_IRQ(CPU_IRQ_BASE + 6, regs);
+       else if (pending & STATUSF_IP0)
+               do_IRQ(CPU_IRQ_BASE, regs);
+       else if (pending & STATUSF_IP1)
+               do_IRQ(CPU_IRQ_BASE + 1, regs);
+
+       vrc5476_irq_dispatch(regs);
+}
+
 void __init arch_init_irq(void)
 {
        /* hardware initialization */
@@ -137,7 +162,4 @@ void __init arch_init_irq(void)
        setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error);
        setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error);
        setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error);
-
-       /* setup the grandpa intr vector */
-       set_except_vector(0, ddb5476_handle_int);
 }
index 581eaba..a3c5e7b 100644 (file)
@@ -77,7 +77,7 @@ vrc5476_irq_init(u32 base)
 }
 
 
-asmlinkage void
+void
 vrc5476_irq_dispatch(struct pt_regs *regs)
 {
        u32 mask;
index b79b43c..ea68815 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for NEC DDB-Vrc5477 board
 #
 
-obj-y                  += int-handler.o irq.o irq_5477.o setup.o lcd44780.o
+obj-y                  += irq.o irq_5477.o setup.o lcd44780.o
 
 obj-$(CONFIG_RUNTIME_DEBUG)    += debug.o
 obj-$(CONFIG_KGDB)             += kgdb_io.o
diff --git a/arch/mips/ddb5xxx/ddb5477/int-handler.S b/arch/mips/ddb5xxx/ddb5477/int-handler.S
deleted file mode 100644 (file)
index 9884874..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * First-level interrupt dispatcher for ddb5477
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/ddb5xxx/ddb5477.h>
-
-/*
- * first level interrupt dispatcher for ocelot board -
- * We check for the timer first, then check PCI ints A and D.
- * Then check for serial IRQ and fall through.
- */
-       .align  5
-       NESTED(ddb5477_handle_int, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-       .set    at
-       .set    noreorder
-       mfc0    t0, CP0_CAUSE
-       mfc0    t2, CP0_STATUS
-
-       and     t0, t2
-
-       andi    t1, t0, STATUSF_IP7     /* cpu timer */
-       bnez    t1, ll_cputimer_irq
-       andi    t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 )
-       bnez    t1, ll_vrc5477_irq
-       andi    t1, t0, STATUSF_IP0     /* software int 0 */
-       bnez    t1, ll_cpu_ip0
-       andi    t1, t0, STATUSF_IP1     /* software int 1 */
-       bnez    t1, ll_cpu_ip1
-       nop
-       .set    reorder
-
-       /* wrong alarm or masked ... */
-       jal     spurious_interrupt
-       j       ret_from_irq
-       END(ddb5477_handle_int)
-
-       .align  5
-
-ll_vrc5477_irq:
-       move    a0, sp
-       jal     vrc5477_irq_dispatch
-       j       ret_from_irq
-
-ll_cputimer_irq:
-       li      a0, CPU_IRQ_BASE + 7
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
-
-
-ll_cpu_ip0:
-       li      a0, CPU_IRQ_BASE + 0
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
-
-ll_cpu_ip1:
-       li      a0, CPU_IRQ_BASE + 1
-       move    a1, sp
-       jal     do_IRQ
-       j       ret_from_irq
index 9ffe1a9..de433cf 100644 (file)
@@ -75,7 +75,6 @@ set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger)
 
 extern void vrc5477_irq_init(u32 base);
 extern void mips_cpu_irq_init(u32 base);
-extern asmlinkage void ddb5477_handle_int(void);
 extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
 static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
 
@@ -135,9 +134,6 @@ void __init arch_init_irq(void)
        /* setup cascade interrupts */
        setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade);
        setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade);
-
-       /* hook up the first-level interrupt handler */
-       set_except_vector(0, ddb5477_handle_int);
 }
 
 u8 i8259_interrupt_ack(void)
@@ -159,7 +155,7 @@ u8 i8259_interrupt_ack(void)
  * the first level int-handler will jump here if it is a vrc5477 irq
  */
 #define        NUM_5477_IRQS   32
-asmlinkage void
+static void
 vrc5477_irq_dispatch(struct pt_regs *regs)
 {
        u32 intStatus;
@@ -197,3 +193,21 @@ vrc5477_irq_dispatch(struct pt_regs *regs)
                }
        }
 }
+
+#define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6)
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status();
+
+       if (pending & STATUSF_IP7)
+               do_IRQ(CPU_IRQ_BASE + 7, regs);
+       else if (pending & VR5477INTS)
+               vrc5477_irq_dispatch(regs);
+       else if (pending & STATUSF_IP0)
+               do_IRQ(CPU_IRQ_BASE, regs);
+       else if (pending & STATUSF_IP1)
+               do_IRQ(CPU_IRQ_BASE + 1, regs);
+       else
+               spurious_interrupt(regs);
+}
index 5bafd58..e8ec93e 100644 (file)
@@ -36,7 +36,7 @@
                .text
                .set    noreorder
 /*
- * decstation_handle_int: Interrupt handler for DECstations
+ * plat_irq_dispatch: Interrupt handler for DECstations
  *
  * We follow the model in the Indy interrupt code by David Miller, where he
  * says: a lot of complication here is taken away because:
  * just take another exception, big deal.
  */
                .align  5
-               NESTED(decstation_handle_int, PT_SIZE, ra)
-               .set    noat
-               SAVE_ALL
-               CLI                             # TEST: interrupts should be off
-               .set    at
+               NESTED(plat_irq_dispatch, PT_SIZE, ra)
                .set    noreorder
 
                /*
@@ -286,7 +282,7 @@ spurious:
                 nop
                j       ret_from_irq
                 nop
-               END(decstation_handle_int)
+               END(plat_irq_dispatch)
 
 /*
  * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl
index 7c1ca8f..ad5d436 100644 (file)
@@ -48,8 +48,6 @@ extern void dec_machine_halt(void);
 extern void dec_machine_power_off(void);
 extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
 
-extern asmlinkage void decstation_handle_int(void);
-
 unsigned long dec_kn_slot_base, dec_kn_slot_size;
 
 EXPORT_SYMBOL(dec_kn_slot_base);
@@ -744,7 +742,6 @@ void __init arch_init_irq(void)
                panic("Don't know how to set this up!");
                break;
        }
-       set_except_vector(0, decstation_handle_int);
 
        /* Free the FPU interrupt if the exception is present. */
        if (!cpu_has_nofpuex) {
index 58c02f9..cd868ec 100644 (file)
@@ -6,4 +6,4 @@
 # Makefile for the Galileo EV96100 board.
 #
 
-obj-y          += init.o irq.o puts.o reset.o time.o int-handler.o setup.o
+obj-y          += init.o irq.o puts.o reset.o time.o setup.o
diff --git a/arch/mips/galileo-boards/ev96100/int-handler.S b/arch/mips/galileo-boards/ev96100/int-handler.S
deleted file mode 100644 (file)
index 0edf1fe..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-       .set    noat
-       .align  5
-
-NESTED(ev96100IRQ, PT_SIZE, sp)
-       SAVE_ALL
-       CLI                             # Important: mark KERNEL mode !
-
-       mfc0    t0, CP0_CAUSE           # get pending interrupts
-       mfc0    t1, CP0_STATUS          # get enabled interrupts
-       and     t0, t1                  # isolate allowed ones
-
-       # FIX ME add R7000 extensions
-       andi    t0,0xff00               # isolate pending bits
-       andi    a0, t0, CAUSEF_IP7
-       beq     a0, zero, 1f
-       move    a0, sp
-       jal     mips_timer_interrupt
-       j       ret_from_irq
-
-1:     beqz    t0, 3f                  # spurious interrupt
-
-       move    a0, t0
-       move    a1, sp
-       jal     ev96100_cpu_irq
-       j       ret_from_irq
-
-3:     jal     spurious_interrupt
-       j       ret_from_irq
-       END(ev96100IRQ)
index 383801d..ee5d672 100644 (file)
@@ -40,8 +40,6 @@
 #include <linux/interrupt.h>
 #include <asm/irq_cpu.h>
 
-extern asmlinkage void ev96100IRQ(void);
-
 static inline unsigned int ffz8(unsigned int word)
 {
        unsigned long k;
@@ -54,13 +52,26 @@ static inline unsigned int ffz8(unsigned int word)
        return k;
 }
 
+extern void mips_timer_interrupt(struct pt_regs *regs);
+
 asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs)
 {
        do_IRQ(ffz8(pending >> 8), regs);
 }
 
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+       if (pending & CAUSEF_IP7)
+               mips_timer_interrupt(regs);
+       else if (pending)
+               ev96100_cpu_irq(pending, regs);
+       else
+               spurious_interrupt(regs);
+}
+
 void __init arch_init_irq(void)
 {
-       set_except_vector(0, ev96100IRQ);
        mips_cpu_irq_init(0);
 }
index ebe91c5..b2c53a8 100644 (file)
@@ -6,6 +6,6 @@
 # Makefile for the Galileo EV64120 board.
 #
 
-obj-y  += int-handler.o irq.o promcon.o reset.o serialGT.o setup.o
+obj-y  += irq.o promcon.o reset.o serialGT.o setup.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/gt64120/ev64120/int-handler.S b/arch/mips/gt64120/ev64120/int-handler.S
deleted file mode 100644 (file)
index 9dda5b4..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * int-handler.S
- *
- * Based on the cobalt handler.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * galileo_handle_int -
- *      We check for the timer first, then check PCI ints A and D.
- *      Then check for serial IRQ and fall through.
- */
-               .align  5
-               .set    reorder
-               .set    noat
-               NESTED(galileo_handle_int, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-               mfc0    t0,CP0_CAUSE
-               mfc0    t2,CP0_STATUS
-
-               and     t0,t2
-
-               andi    t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */
-               bnez    t1,ll_gt64120_irq
-               andi    t1,t0,STATUSF_IP2 /* int0 hardware line */
-               bnez    t1,ll_pci_intA
-               andi    t1,t0,STATUSF_IP5 /* int3 hardware line */
-               bnez    t1,ll_pci_intD
-               andi    t1,t0,STATUSF_IP6 /* int4 hardware line */
-               bnez    t1,ll_serial_irq
-               andi    t1,t0,STATUSF_IP7 /* compare int */
-               bnez    t1,ll_compare_irq
-               nop
-
-    /* wrong alarm or masked ... */
-               jal     spurious_interrupt
-               nop
-               j       ret_from_irq
-               END(galileo_handle_int)
-
-
-               .align  5
-               .set    reorder
-ll_gt64120_irq:
-               li      a0,4
-               move    a1,sp
-               jal     do_IRQ
-               nop
-               j       ret_from_irq
-               nop
-
-               .align  5
-               .set    reorder
-ll_compare_irq:
-               li      a0,7
-               move    a1,sp
-               jal     do_IRQ
-               nop
-               j       ret_from_irq
-               nop
-
-               .align  5
-               .set    reorder
-ll_pci_intA:
-               move    a0,sp
-               jal     pci_intA
-               nop
-               j       ret_from_irq
-               nop
-
-#if 0
-               .align  5
-               .set    reorder
-ll_pci_intB:
-               move    a0,sp
-               jal     pci_intB
-               nop
-               j       ret_from_irq
-               nop
-
-               .align  5
-               .set    reorder
-ll_pci_intC:
-               move    a0,sp
-               jal     pci_intC
-               nop
-               j       ret_from_irq
-               nop
-#endif
-
-               .align  5
-               .set    reorder
-ll_pci_intD:
-               move    a0,sp
-               jal     pci_intD
-               nop
-               j       ret_from_irq
-               nop
-
-               .align  5
-               .set    reorder
-ll_serial_irq:
-               li      a0,6
-               move    a1,sp
-               jal     do_IRQ
-               nop
-               j       ret_from_irq
-               nop
index 3b18615..46c468b 100644 (file)
 #include <asm/system.h>
 #include <asm/gt64120.h>
 
-asmlinkage inline void pci_intA(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 {
-       do_IRQ(GT_INTA, regs);
-}
-
-asmlinkage inline void pci_intD(struct pt_regs *regs)
-{
-       do_IRQ(GT_INTD, regs);
+       unsigned int pending = read_c0_status() & read_c0_cause();
+
+       if (pending & STATUSF_IP4)              /* int2 hardware line (timer) */
+               do_IRQ(4, regs);
+       else if (pending & STATUSF_IP2)         /* int0 hardware line */
+               do_IRQ(GT_INTA, regs);
+       else if (pending & STATUSF_IP5)         /* int3 hardware line */
+               do_IRQ(GT_INTD, regs);
+       else if (pending & STATUSF_IP6)         /* int4 hardware line */
+               do_IRQ(6, regs);
+       else if (pending & STATUSF_IP7)         /* compare int */
+               do_IRQ(7, regs);
+       else
+               spurious_interrupt(regs);
 }
 
 static void disable_ev64120_irq(unsigned int irq_nr)
@@ -109,16 +117,11 @@ static struct hw_interrupt_type ev64120_irq_type = {
 
 void gt64120_irq_setup(void)
 {
-       extern asmlinkage void galileo_handle_int(void);
-
        /*
         * Clear all of the interrupts while we change the able around a bit.
         */
        clear_c0_status(ST0_IM);
 
-       /* Sets the exception_handler array. */
-       set_except_vector(0, galileo_handle_int);
-
        local_irq_disable();
 
        /*
index 7b59c65..6f708df 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for Momentum's Ocelot board.
 #
 
-obj-y                  += int-handler.o irq.o prom.o reset.o setup.o
+obj-y                  += irq.o prom.o reset.o setup.o
 
 obj-$(CONFIG_KGDB)     += dbg_io.o
 
diff --git a/arch/mips/gt64120/momenco_ocelot/int-handler.S b/arch/mips/gt64120/momenco_ocelot/int-handler.S
deleted file mode 100644 (file)
index 808acef..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * First-level interrupt dispatcher for ocelot board.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * first level interrupt dispatcher for ocelot board -
- * We check for the timer first, then check PCI ints A and D.
- * Then check for serial IRQ and fall through.
- */
-               .align  5
-               NESTED(ocelot_handle_int, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-               mfc0    t0, CP0_CAUSE
-               mfc0    t2, CP0_STATUS
-
-               and     t0, t2
-
-                andi   t1, t0, STATUSF_IP2     /* int0 hardware line */
-               bnez    t1, ll_pri_enet_irq
-                andi   t1, t0, STATUSF_IP3     /* int1 hardware line */
-               bnez    t1, ll_sec_enet_irq
-                andi   t1, t0, STATUSF_IP4     /* int2 hardware line */
-               bnez    t1, ll_uart1_irq
-                andi   t1, t0, STATUSF_IP5     /* int3 hardware line */
-               bnez    t1, ll_cpci_irq
-                andi   t1, t0, STATUSF_IP6     /* int4 hardware line */
-               bnez    t1, ll_galileo_irq
-                andi   t1, t0, STATUSF_IP7     /* cpu timer */
-               bnez    t1, ll_cputimer_irq
-
-                /* now look at the extended interrupts */
-               mfc0    t0, CP0_CAUSE
-               cfc0    t1, CP0_S1_INTCONTROL
-
-               /* shift the mask 8 bits left to line up the bits */
-                sll    t2, t1, 8
-
-                and    t0, t2
-                srl    t0, t0, 16
-
-                andi   t1, t0, STATUSF_IP8     /* int6 hardware line */
-               bnez    t1, ll_pmc1_irq
-                andi   t1, t0, STATUSF_IP9     /* int7 hardware line */
-               bnez    t1, ll_pmc2_irq
-                andi   t1, t0, STATUSF_IP10    /* int8 hardware line */
-               bnez    t1, ll_cpci_abcd_irq
-                andi   t1, t0, STATUSF_IP11    /* int9 hardware line */
-               bnez    t1, ll_uart2_irq
-
-               .set    reorder
-
-               /* wrong alarm or masked ... */
-               j       spurious_interrupt
-               nop
-               END(ocelot_handle_int)
-
-               .align  5
-ll_pri_enet_irq:
-               li      a0, 2
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_sec_enet_irq:
-               li      a0, 3
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_uart1_irq:
-               li      a0, 4
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_cpci_irq:
-               li      a0, 5
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_galileo_irq:
-               li      a0, 6
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_cputimer_irq:
-               li      a0, 7
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pmc1_irq:
-               li      a0, 8
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pmc2_irq:
-               li      a0, 9
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_cpci_abcd_irq:
-               li      a0, 10
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_uart2_irq:
-               li      a0, 11
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
index 4f108da..885f67f 100644 (file)
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-extern asmlinkage void ocelot_handle_int(void);
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_status() & read_c0_cause();
+
+       if (pending & STATUSF_IP2)              /* int0 hardware line */
+               do_IRQ(2, regs);
+       else if (pending & STATUSF_IP3)         /* int1 hardware line */
+               do_IRQ(3, regs);
+       else if (pending & STATUSF_IP4)         /* int2 hardware line */
+               do_IRQ(4, regs);
+       else if (pending & STATUSF_IP5)         /* int3 hardware line */
+               do_IRQ(5, regs);
+       else if (pending & STATUSF_IP6)         /* int4 hardware line */
+               do_IRQ(6, regs);
+       else if (pending & STATUSF_IP7)         /* cpu timer */
+               do_IRQ(7, regs);
+       else {
+               /*
+                * Now look at the extended interrupts
+                */
+               pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
+
+               if (pending & STATUSF_IP8)              /* int6 hardware line */
+                       do_IRQ(8, regs);
+               else if (pending & STATUSF_IP9)         /* int7 hardware line */
+                       do_IRQ(9, regs);
+               else if (pending & STATUSF_IP10)        /* int8 hardware line */
+                       do_IRQ(10, regs);
+               else if (pending & STATUSF_IP11)        /* int9 hardware line */
+                       do_IRQ(11, regs);
+       }
+}
 
 void __init arch_init_irq(void)
 {
@@ -59,9 +90,6 @@ void __init arch_init_irq(void)
        clear_c0_status(ST0_IM);
        local_irq_disable();
 
-       /* Sets the first-level interrupt dispatcher. */
-       set_except_vector(0, ocelot_handle_int);
-
        mips_cpu_irq_init(0);
        rm7k_cpu_irq_init(8);
 }
index 0e7853f..6343153 100644 (file)
@@ -6,7 +6,7 @@
 # Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
 #
 
-obj-y                  += it8172_setup.o irq.o int-handler.o pmon_prom.o \
+obj-y                  += it8172_setup.o irq.o pmon_prom.o \
                           time.o lpc.o puts.o reset.o
 
 obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o
diff --git a/arch/mips/ite-boards/generic/int-handler.S b/arch/mips/ite-boards/generic/int-handler.S
deleted file mode 100644 (file)
index d190d8a..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-       .text
-       .set    macro
-       .set    noat
-       .align  5
-
-NESTED(it8172_IRQ, PT_SIZE, sp)
-       SAVE_ALL
-       CLI                             # Important: mark KERNEL mode !
-
-        /* We're working with 'reorder' set at this point. */
-       /*
-        * Get pending interrupts
-        */
-
-       mfc0    t0,CP0_CAUSE            # get pending interrupts
-       mfc0    t1,CP0_STATUS           # get enabled interrupts
-       and     t0,t1                   # isolate allowed ones
-
-       andi    t0,0xff00               # isolate pending bits
-        beqz    t0, 3f                  # spurious interrupt
-
-        andi    a0, t0, CAUSEF_IP7
-        beq     a0, zero, 1f
-
-        li     a0, 127                 # MIPS_CPU_TIMER_IRQ = (NR_IRQS-1)
-        move    a1, sp
-        jal     ll_timer_interrupt
-       j       ret_from_irq
-        nop
-
-1:
-        andi    a0, t0, CAUSEF_IP2      # the only int we expect at this time
-        beq     a0, zero, 3f
-       move    a0,sp
-       jal     it8172_hw0_irqdispatch
-
-       mfc0    t0,CP0_STATUS           # disable interrupts
-       ori     t0,1
-       xori    t0,1
-       mtc0    t0,CP0_STATUS
-        nop
-        nop
-        nop
-
-       la      a1, ret_from_irq
-       jr      a1
-        nop
-
-3:
-       move a0, sp
-       jal     mips_spurious_interrupt
-        nop
-       la      a1, ret_from_irq
-       jr      a1
-        nop
-
-END(it8172_IRQ)
-
index 8c1cdfc..77be721 100644 (file)
@@ -64,7 +64,6 @@
 
 extern void set_debug_traps(void);
 extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
-extern asmlinkage void it8172_IRQ(void);
 
 struct it8172_intc_regs volatile *it8172_hw0_icregs =
        (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
@@ -178,8 +177,6 @@ void __init arch_init_irq(void)
        int i;
         unsigned long flags;
 
-        set_except_vector(0, it8172_IRQ);
-
        /* mask all interrupts */
        it8172_hw0_icregs->lb_mask  = 0xffff;
        it8172_hw0_icregs->lpc_mask = 0xffff;
@@ -279,6 +276,18 @@ void it8172_hw0_irqdispatch(struct pt_regs *regs)
        do_IRQ(irq, regs);
 }
 
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+       if (!pending)
+               mips_spurious_interrupt(regs);
+       else if (pending & CAUSEF_IP7)
+               ll_timer_interrupt(127, regs);
+       else if (pending & CAUSEF_IP2)
+               it8172_hw0_irqdispatch(regs);
+}
+
 void show_pending_irqs(void)
 {
        fputs("intstatus:  ");
index 8574924..02bd39a 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for the Jazz family specific parts of the kernel
 #
 
-obj-y          := int-handler.o irq.o jazzdma.o reset.o setup.o
+obj-y          := irq.o jazzdma.o reset.o setup.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/jazz/int-handler.S b/arch/mips/jazz/int-handler.S
deleted file mode 100644 (file)
index e35f5fc..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle and Andreas Busse
- *
- * Jazz family specific interrupt stuff
- *
- * To do: On Jazz machines we remap some non-ISA interrupts to ISA
- *        interrupts.  These interrupts should use their own vectors.
- *        Squeeze the last cycles out of the handlers.  Only a dead
- *        cycle is a good cycle.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/jazz.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * jazz_handle_int: Interrupt handler for the ACER Pica-61 boards
- */
-               .set    noreorder
-
-               NESTED(jazz_handle_int, PT_SIZE, ra)
-               .set    noat
-               SAVE_ALL
-               CLI
-               .set    at
-
-               /*
-                * Get pending interrupts
-                */
-               mfc0    t0,CP0_CAUSE            # get pending interrupts
-               mfc0    t1,CP0_STATUS           # get enabled interrupts
-               and     t0,t1                   # isolate allowed ones
-               andi    t0,0xff00               # isolate pending bits
-               beqz    t0,3f
-               sll     t0,16                   # delay slot
-
-               /*
-                * Find irq with highest priority
-                * FIXME: This is slow - use binary search
-                */
-               la      t1,ll_vectors
-1:             bltz    t0,2f                   # found pending irq
-               sll     t0,1
-               b       1b
-               subu    t1,PTRSIZE              # delay slot
-
-               /*
-                * Do the low-level stuff
-                */
-2:             lw      t0,(t1)
-               jr      t0
-               nop                             # delay slot
-               END(jazz_handle_int)
-
-ll_sw0:                li      s1,~IE_SW0
-               mfc0    t0,CP0_CAUSE
-               and     t0,s1
-               mtc0    t0,CP0_CAUSE
-               PANIC("Unimplemented sw0 handler")
-
-ll_sw1:                li      s1,~IE_SW1
-               mfc0    t0,CP0_CAUSE
-               and     t0,s1
-               mtc0    t0,CP0_CAUSE
-               PANIC("Unimplemented sw1 handler")
-
-ll_local_dma:  li      s1,~IE_IRQ0
-               PANIC("Unimplemented local_dma handler")
-
-ll_local_dev:  lbu     t0,JAZZ_IO_IRQ_SOURCE
-#if PTRSIZE == 8       /* True 64 bit kernel */
-               dsll    t0,1
-#endif
-               .set    reorder
-               LONG_L  t0,local_vector(t0)
-               jr      t0
-               .set    noreorder
-
-/*
- * The braindead PICA hardware gives us no way to distinguish if we really
- * received interrupt 7 from the (E)ISA bus or if we just received an
- * interrupt with no findable cause.  This sometimes happens with braindead
- * cards.  Oh well - for all the Jazz boxes slots are more or less just
- * whistles and bells and we're aware of the problem.
- */
-ll_isa_irq:    lw      a0, JAZZ_EISA_IRQ_ACK
-
-               jal     do_IRQ
-                move   a1,sp
-
-               j       ret_from_irq
-               nop
-
-/*
- * Hmm...  This is not just a plain PC clone so the question is
- * which devices on Jazz machines can generate an (E)ISA NMI?
- * (Writing to nonexistent memory?)
- */
-ll_isa_nmi:    li      s1,~IE_IRQ3
-               PANIC("Unimplemented isa_nmi handler")
-
-/*
- * Timer IRQ - remapped to be more similar to an IBM compatible.
- *
- * The timer interrupt is handled specially to ensure that the jiffies
- * variable is updated at all times.  Specifically, the timer interrupt is
- * just like the complete handlers except that it is invoked with interrupts
- * disabled and should never re-enable them.  If other interrupts were
- * allowed to be processed while the timer interrupt is active, then the
- * other interrupts would have to avoid using the jiffies variable for delay
- * and interval timing operations to avoid hanging the system.
- */
-ll_timer:      lw      zero,JAZZ_TIMER_REGISTER # timer irq cleared on read
-               li      s1,~IE_IRQ4
-
-               li      a0, JAZZ_TIMER_IRQ
-               jal     do_IRQ
-                move   a1,sp
-
-               mfc0    t0,CP0_STATUS           # disable interrupts again
-               ori     t0,1
-               xori    t0,1
-               mtc0    t0,CP0_STATUS
-
-               j       ret_from_irq
-                nop
-
-/*
- * CPU count/compare IRQ (unused)
- */
-ll_count:      j       ret_from_irq
-                mtc0   zero,CP0_COMPARE
-
-#if 0
-/*
- * Call the handler for the interrupt
- * (Currently unused)
- */
-call_real:     /*
-                * temporarily disable interrupt
-                */
-               mfc0    t2,CP0_STATUS
-               and     t2,s1
-               mtc0    t2,CP0_STATUS
-               nor     s1,zero,s1
-               jal     do_IRQ
-
-               /*
-                * reenable interrupt
-                */
-               mfc0    t2,CP0_STATUS
-               or      t2,s1
-               mtc0    t2,CP0_STATUS
-               j       ret_from_irq
-#endif
-
-               .data
-               PTR     ll_sw0                  # SW0
-               PTR     ll_sw1                  # SW1
-               PTR     ll_local_dma            # Local DMA
-               PTR     ll_local_dev            # Local devices
-               PTR     ll_isa_irq              # ISA IRQ
-               PTR     ll_isa_nmi              # ISA NMI
-               PTR     ll_timer                # Timer
-ll_vectors:    PTR     ll_count                # Count/Compare IRQ
-
-               /*
-                * Interrupt handlers for local devices.
-                */
-               .text
-               .set    reorder
-loc_no_irq:    PANIC("Unimplemented loc_no_irq handler")
-/*
- * Parallel port IRQ
- */
-loc_parallel:  li      s1,~JAZZ_IE_PARALLEL
-               li      a0,JAZZ_PARALLEL_IRQ
-               b       loc_call
-
-/*
- * Floppy IRQ
- */
-loc_floppy:    li      s1,~JAZZ_IE_FLOPPY
-               li      a0,JAZZ_FLOPPY_IRQ
-               b       loc_call
-
-/*
- * Sound IRQ
- */
-loc_sound:     PANIC("Unimplemented loc_sound handler")
-loc_video:     PANIC("Unimplemented loc_video handler")
-
-/*
- * Ethernet interrupt handler
- */
-loc_ethernet:  li      s1,~JAZZ_IE_ETHERNET
-               li      a0,JAZZ_ETHERNET_IRQ
-               b       loc_call
-
-/*
- * SCSI interrupt handler
- */
-loc_scsi:      li      s1,~JAZZ_IE_SCSI
-               li      a0,JAZZ_SCSI_IRQ
-               b       loc_call
-
-/*
- * Keyboard interrupt handler
- */
-loc_keyboard:  li      s1,~JAZZ_IE_KEYBOARD
-               li      a0,JAZZ_KEYBOARD_IRQ
-               b       loc_call
-
-/*
- * Mouse interrupt handler
- */
-loc_mouse:     li      s1,~JAZZ_IE_MOUSE
-               li      a0,JAZZ_MOUSE_IRQ
-               b       loc_call
-
-/*
- * Serial port 1 IRQ
- */
-loc_serial1:   li      s1,~JAZZ_IE_SERIAL1
-               li      a0,JAZZ_SERIAL1_IRQ
-               b       loc_call
-
-/*
- * Serial port 2 IRQ
- */
-loc_serial2:   li      s1,~JAZZ_IE_SERIAL2
-               li      a0,JAZZ_SERIAL2_IRQ
-               b       loc_call
-
-/*
- * Call the interrupt handler for an interrupt generated by a
- * local device.
- */
-loc_call:      /*
-                * Temporarily disable interrupt source
-                */
-               lhu     t2,JAZZ_IO_IRQ_ENABLE
-               and     t2,s1
-               sh      t2,JAZZ_IO_IRQ_ENABLE
-
-               nor     s1,zero,s1
-               jal     do_IRQ
-
-               /*
-                * Reenable interrupt
-                */
-               lhu     t2,JAZZ_IO_IRQ_ENABLE
-               or      t2,s1
-               sh      t2,JAZZ_IO_IRQ_ENABLE
-
-               j       ret_from_irq
-
-/*
- * "Jump extender" to reach spurious_interrupt
- */
-3:             jal     spurious_interrupt
-               j       ret_from_irq
-
-/*
- * Vectors for interrupts generated by local devices
- */
-               .data
-local_vector:  PTR     loc_no_irq
-               PTR     loc_parallel
-               PTR     loc_floppy
-               PTR     loc_sound
-               PTR     loc_video
-               PTR     loc_ethernet
-               PTR     loc_scsi
-               PTR     loc_keyboard
-               PTR     loc_mouse
-               PTR     loc_serial1
-               PTR     loc_serial2
index b309b1b..becc9ac 100644 (file)
@@ -15,8 +15,6 @@
 #include <asm/io.h>
 #include <asm/jazz.h>
 
-extern asmlinkage void jazz_handle_int(void);
-
 static DEFINE_SPINLOCK(r4030_lock);
 
 static void enable_r4030_irq(unsigned int irq)
@@ -90,10 +88,82 @@ void __init init_r4030_ints(void)
  */
 void __init arch_init_irq(void)
 {
-       set_except_vector(0, jazz_handle_int);
-
        init_i8259_irqs();                      /* Integrated i8259  */
        init_r4030_ints();
 
        change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
 }
+
+static void loc_call(unsigned int irq, struct pt_regs *regs, unsigned int mask)
+{
+       r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
+                         r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask);
+       do_IRQ(irq, regs);
+       r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
+                         r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask);
+}
+
+static void ll_local_dev(struct pt_regs *regs)
+{
+       switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) {
+       case 0:
+               panic("Unimplemented loc_no_irq handler");
+               break;
+       case 4:
+               loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_PARALLEL);
+               break;
+       case 8:
+               loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_FLOPPY);
+               break;
+       case 12:
+               panic("Unimplemented loc_sound handler");
+               break;
+       case 16:
+               panic("Unimplemented loc_video handler");
+               break;
+       case 20:
+               loc_call(JAZZ_ETHERNET_IRQ, regs, JAZZ_IE_ETHERNET);
+               break;
+       case 24:
+               loc_call(JAZZ_SCSI_IRQ, regs, JAZZ_IE_SCSI);
+               break;
+       case 28:
+               loc_call(JAZZ_KEYBOARD_IRQ, regs, JAZZ_IE_KEYBOARD);
+               break;
+       case 32:
+               loc_call(JAZZ_MOUSE_IRQ, regs, JAZZ_IE_MOUSE);
+               break;
+       case 36:
+               loc_call(JAZZ_SERIAL1_IRQ, regs, JAZZ_IE_SERIAL1);
+               break;
+       case 40:
+               loc_call(JAZZ_SERIAL2_IRQ, regs, JAZZ_IE_SERIAL2);
+               break;
+       }
+}
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+       if (pending & IE_IRQ5)
+               write_c0_compare(0);
+       else if (pending & IE_IRQ4) {
+               r4030_read_reg32(JAZZ_TIMER_REGISTER);
+               do_IRQ(JAZZ_TIMER_IRQ, regs);
+       } else if (pending & IE_IRQ3)
+               panic("Unimplemented ISA NMI handler");
+       else if (pending & IE_IRQ2)
+               do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK), regs);
+       else if (pending & IE_IRQ1) {
+               ll_local_dev(regs);
+       } else if (unlikely(pending & IE_IRQ0))
+               panic("Unimplemented local_dma handler");
+       else if (pending & IE_SW1) {
+               clear_c0_cause(IE_SW1);
+               panic("Unimplemented sw1 handler");
+       } else if (pending & IE_SW0) {
+               clear_c0_cause(IE_SW0);
+               panic("Unimplemented sw0 handler");
+       }
+}
index 75bf418..baf5077 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for TOSHIBA JMR-TX3927 board
 #
 
-obj-y                          += init.o int-handler.o irq.o setup.o
+obj-y                          += init.o irq.o setup.o
 obj-$(CONFIG_RUNTIME_DEBUG)    += debug.o
 obj-$(CONFIG_KGDB)             += kgdb_io.o
 
diff --git a/arch/mips/jmr3927/rbhma3100/int-handler.S b/arch/mips/jmr3927/rbhma3100/int-handler.S
deleted file mode 100644 (file)
index f85bbf4..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *              ahennessy@mvista.com
- *
- * Based on arch/mips/tsdb/kernel/int-handler.S
- *
- * Copyright (C) 2000-2001 Toshiba Corporation
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/jmr3927/jmr3927.h>
-
-       /* A lot of complication here is taken away because:
-        *
-        * 1) We handle one interrupt and return, sitting in a loop
-        *    and moving across all the pending IRQ bits in the cause
-        *    register is _NOT_ the answer, the common case is one
-        *    pending IRQ so optimize in that direction.
-        *
-        * 2) We need not check against bits in the status register
-        *    IRQ mask, that would make this routine slow as hell.
-        *
-        * 3) Linux only thinks in terms of all IRQs on or all IRQs
-        *    off, nothing in between like BSD spl() brain-damage.
-        *
-        */
-
-/* Flush write buffer (needed?)
- * NOTE: TX39xx performs "non-blocking load", so explicitly use the target
- * register of LBU to flush immediately.
- */
-#define FLUSH_WB(tmp)  \
-       la      tmp, JMR3927_IOC_REV_ADDR; \
-       lbu     tmp, (tmp); \
-       move    tmp, zero;
-
-       .text
-       .set    noreorder
-       .set    noat
-       .align  5
-       NESTED(jmr3927_IRQ, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-       .set    at
-       jal     jmr3927_irc_irqdispatch
-        move   a0, sp
-       FLUSH_WB(t0)
-       j       ret_from_irq
-        nop
-       END(jmr3927_IRQ)
index 2810727..11304d1 100644 (file)
@@ -77,8 +77,6 @@ static int jmr3927_gen_iack(void)
 }
 #endif
 
-extern asmlinkage void jmr3927_IRQ(void);
-
 #define irc_dlevel     0
 #define irc_elevel     1
 
@@ -262,7 +260,7 @@ void jmr3927_spurious(struct pt_regs *regs)
               regs->cp0_cause, regs->cp0_epc, regs->regs[31]);
 }
 
-void jmr3927_irc_irqdispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 {
        int irq;
 
@@ -398,8 +396,6 @@ void __init arch_init_irq(void)
 
        jmr3927_irq_init(NR_ISA_IRQS);
 
-       set_except_vector(0, jmr3927_IRQ);
-
        /* setup irq space */
        add_tb_irq_space(&jmr3927_isac_irqspace);
        add_tb_irq_space(&jmr3927_ioc_irqspace);
index 13f22d1..04418b6 100644 (file)
@@ -122,6 +122,20 @@ handle_vcei:
        .set    pop
        END(except_vec3_r4000)
 
+       __FINIT
+
+       .align  5
+NESTED(handle_int, PT_SIZE, sp)
+       SAVE_ALL
+       CLI
+
+       PTR_LA  ra, ret_from_irq
+       move    a0, sp
+       j       plat_irq_dispatch
+       END(handle_int)
+
+       __INIT
+
 /*
  * Special interrupt vector for MIPS64 ISA & embedded MIPS processors.
  * This is a dedicated interrupt exception vector which reduces the
index 8573190..61efc61 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/watch.h>
 #include <asm/types.h>
 
+extern asmlinkage void handle_int(void);
 extern asmlinkage void handle_tlbm(void);
 extern asmlinkage void handle_tlbl(void);
 extern asmlinkage void handle_tlbs(void);
@@ -1296,6 +1297,7 @@ void __init trap_init(void)
        if (board_be_init)
                board_be_init();
 
+       set_except_vector(0, handle_int);
        set_except_vector(1, handle_tlbm);
        set_except_vector(2, handle_tlbl);
        set_except_vector(3, handle_tlbs);
index 0d5aec4..99f5046 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 obj-y                          += reset.o setup.o prom.o lasat_board.o \
-                                  at93c.o interrupt.o lasatIRQ.o
+                                  at93c.o interrupt.o
 
 obj-$(CONFIG_LASAT_SYSCTL)     += sysctl.o
 obj-$(CONFIG_DS1603)           += ds1603.o
index 852a419..2d3472b 100644 (file)
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
 #include <asm/lasat/lasatint.h>
+#include <asm/time.h>
 #include <asm/gdb-stub.h>
 
 static volatile int *lasat_int_status = NULL;
 static volatile int *lasat_int_mask = NULL;
 static volatile int lasat_int_mask_shift;
 
-extern asmlinkage void lasatIRQ(void);
-
 void disable_lasat_irq(unsigned int irq_nr)
 {
        unsigned long flags;
@@ -109,11 +108,17 @@ static unsigned long get_int_status_200(void)
        return int_status;
 }
 
-void lasat_hw0_irqdispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 {
        unsigned long int_status;
+       unsigned int cause = read_c0_cause();
        int irq;
 
+       if (cause & CAUSEF_IP7) {       /* R4000 count / compare IRQ */
+               ll_timer_interrupt(7, regs);
+               return;
+       }
+
        int_status = get_int_status();
 
        /* if int_status == 0, then the interrupt has already been cleared */
@@ -147,9 +152,6 @@ void __init arch_init_irq(void)
                panic("arch_init_irq: mips_machtype incorrect");
        }
 
-       /* Now safe to set the exception vector. */
-       set_except_vector(0, lasatIRQ);
-
        for (i = 0; i <= LASATINT_END; i++) {
                irq_desc[i].status      = IRQ_DISABLED;
                irq_desc[i].action      = 0;
diff --git a/arch/mips/lasat/lasatIRQ.S b/arch/mips/lasat/lasatIRQ.S
deleted file mode 100644 (file)
index 2a2b0d0..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Interrupt exception dispatch code.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-       .text
-       .set    noreorder
-       .align  5
-       NESTED(lasatIRQ, PT_SIZE, sp)
-       .set    noat
-       SAVE_ALL
-       CLI
-       .set    at
-       .set    noreorder
-
-       mfc0    s0, CP0_CAUSE           # get irq mask
-
-       /* First we check for r4k counter/timer IRQ. */
-       andi    a0, s0, CAUSEF_IP7
-       beq     a0, zero, 1f
-        andi   a0, s0, CAUSEF_IP2      # delay slot, check hw0 interrupt
-
-       /* Wheee, a timer interrupt. */
-       li      a0, 7
-       jal     ll_timer_interrupt
-        move   a1, sp
-
-       j       ret_from_irq
-        nop
-
-1:
-       /* Wheee, combined hardware level zero interrupt. */
-       jal     lasat_hw0_irqdispatch
-        move   a0, sp                  # delay slot
-
-       j       ret_from_irq
-        nop                            # delay slot
-
-1:
-       /*
-        * Here by mistake?  This is possible, what can happen is that by the
-        * time we take the exception the IRQ pin goes low, so just leave if
-        * this is the case.
-        */
-       move    a1,s0
-       mfc0    a1, CP0_EPC
-
-       j       ret_from_irq
-        nop
-       END(lasatIRQ)
index 50fec2a..d8dab75 100644 (file)
@@ -16,5 +16,5 @@
 # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 #
 
-obj-y                  := atlas_int.o atlas-irq.o atlas_setup.o
+obj-y                  := atlas_int.o atlas_setup.o
 obj-$(CONFIG_KGDB)     += atlas_gdb.o
diff --git a/arch/mips/mips-boards/atlas/atlas-irq.S b/arch/mips/mips-boards/atlas/atlas-irq.S
deleted file mode 100644 (file)
index 31bc99a..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Interrupt exception dispatch code.
- */
-#include <linux/config.h>
-
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/mips-boards/atlasint.h>
-
-/*
- * Furthermore, the IRQs on the MIPS board look basically (barring software
- * IRQs which we don't use at all and all external interrupt sources are
- * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
- *
- *     MIPS IRQ        Source
- *      --------        ------
- *             0       Software (ignored)
- *             1        Software (ignored)
- *             2        Combined hardware interrupt (hw0)
- *             3        Hardware (ignored)
- *             4        Hardware (ignored)
- *             5        Hardware (ignored)
- *             6        Hardware (ignored)
- *             7        R4k timer (what we use)
- *
- * Note: On the SEAD board thing are a little bit different.
- *       Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
- *       wired to UART1.
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ----     R4k Timer
- * Lowest  ----     Combined hardware interrupt
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
-       .text
-       .set    noreorder
-       .set    noat
-       .align  5
-       NESTED(mipsIRQ, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-       .set    at
-
-       mfc0    s0, CP0_CAUSE           # get irq bits
-       mfc0    s1, CP0_STATUS          # get irq mask
-       andi    s0, ST0_IM              # CAUSE.CE may be non-zero!
-       and     s0, s1
-
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-       .set    mips32
-       clz     a0, s0
-       .set    mips0
-       negu    a0
-       addu    a0, 31-CAUSEB_IP
-       bltz    a0, spurious
-#else
-       beqz    s0, spurious
-        li     a0, 7
-
-       and     t0, s0, 0xf000
-       sltiu   t0, t0, 1
-       sll     t0, 2
-       subu    a0, t0
-       sll     s0, t0
-
-       and     t0, s0, 0xc000
-       sltiu   t0, t0, 1
-       sll     t0, 1
-       subu    a0, t0
-       sll     s0, t0
-
-       and     t0, s0, 0x8000
-       sltiu   t0, t0, 1
-       # sll   t0, 0
-       subu    a0, t0
-       # sll   s0, t0
-#endif
-
-        li     a1, MIPSCPU_INT_ATLAS
-       bne     a0, a1, 1f
-        addu   a0, MIPSCPU_INT_BASE
-
-       jal     atlas_hw0_irqdispatch
-        move    a0, sp
-
-       j       ret_from_irq
-        nop
-
-1:     jal     do_IRQ
-        move   a1, sp
-
-       j       ret_from_irq
-        nop
-
-spurious:
-       j       spurious_interrupt
-        nop
-       END(mipsIRQ)
index bc0ebc6..db53950 100644 (file)
@@ -39,8 +39,6 @@
 
 static struct atlas_ictrl_regs *atlas_hw0_icregs;
 
-extern asmlinkage void mipsIRQ(void);
-
 #if 0
 #define DEBUG_INT(x...) printk(x)
 #else
@@ -98,7 +96,7 @@ static inline int ls1bit32(unsigned int x)
        return b;
 }
 
-void atlas_hw0_irqdispatch(struct pt_regs *regs)
+static inline void atlas_hw0_irqdispatch(struct pt_regs *regs)
 {
        unsigned long int_status;
        int irq;
@@ -116,6 +114,91 @@ void atlas_hw0_irqdispatch(struct pt_regs *regs)
        do_IRQ(irq, regs);
 }
 
+static inline int clz(unsigned long x)
+{
+       __asm__ (
+       "       .set    push                                    \n"
+       "       .set    mips32                                  \n"
+       "       clz     %0, %1                                  \n"
+       "       .set    pop                                     \n"
+       : "=r" (x)
+       : "r" (x));
+
+       return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+       return -clz(pending) + 31 - CAUSEB_IP;
+#else
+       unsigned int a0 = 7;
+       unsigned int t0;
+
+       t0 = s0 & 0xf000;
+       t0 = t0 < 1;
+       t0 = t0 << 2;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
+
+       t0 = s0 & 0xc000;
+       t0 = t0 < 1;
+       t0 = t0 << 1;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
+
+       t0 = s0 & 0x8000;
+       t0 = t0 < 1;
+       //t0 = t0 << 2;
+       a0 = a0 - t0;
+       //s0 = s0 << t0;
+
+       return a0;
+#endif
+}
+
+/*
+ * IRQs on the Atlas board look basically (barring software IRQs which we
+ * don't use at all and all external interrupt sources are combined together
+ * on hardware interrupt 0 (MIPS IRQ 2)) like:
+ *
+ *     MIPS IRQ        Source
+ *      --------        ------
+ *             0       Software (ignored)
+ *             1        Software (ignored)
+ *             2        Combined hardware interrupt (hw0)
+ *             3        Hardware (ignored)
+ *             4        Hardware (ignored)
+ *             5        Hardware (ignored)
+ *             6        Hardware (ignored)
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ * Lowest  ----     Combined hardware interrupt
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+       int irq;
+
+       irq = irq_ffs(pending);
+
+       if (irq == MIPSCPU_INT_ATLAS)
+               atlas_hw0_irqdispatch(regs);
+       else if (irq > 0)
+               do_IRQ(MIPSCPU_INT_BASE + irq, regs);
+       else
+               spurious_interrupt(regs);
+}
+
 void __init arch_init_irq(void)
 {
        int i;
@@ -128,9 +211,6 @@ void __init arch_init_irq(void)
         */
        atlas_hw0_icregs->intrsten = 0xffffffff;
 
-       /* Now safe to set the exception vector. */
-       set_except_vector(0, mipsIRQ);
-
        for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) {
                irq_desc[i].status      = IRQ_DISABLED;
                irq_desc[i].action      = 0;
index 3ae8fe6..fd4c143 100644 (file)
@@ -19,4 +19,4 @@
 # under Linux.
 #
 
-obj-y := malta_int.o malta-irq.o malta_setup.o
+obj-y := malta_int.o malta_setup.o
diff --git a/arch/mips/mips-boards/malta/malta-irq.S b/arch/mips/mips-boards/malta/malta-irq.S
deleted file mode 100644 (file)
index 6217aff..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Interrupt exception dispatch code.
- *
- */
-#include <linux/config.h>
-
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/mips-boards/maltaint.h>
-
-/*
- * IRQs on the Malta board look basically (barring software IRQs which we
- * don't use at all and all external interrupt sources are combined together
- * on hardware interrupt 0 (MIPS IRQ 2)) like:
- *
- *     MIPS IRQ        Source
- *      --------        ------
- *             0       Software (ignored)
- *             1        Software (ignored)
- *             2        Combined hardware interrupt (hw0)
- *             3        Hardware (ignored)
- *             4        Hardware (ignored)
- *             5        Hardware (ignored)
- *             6        Hardware (ignored)
- *             7        R4k timer (what we use)
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ----     R4k Timer
- * Lowest  ----     Combined hardware interrupt
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
-       .text
-       .set    noreorder
-       .set    noat
-       .align  5
-       NESTED(mipsIRQ, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-       .set    at
-
-       mfc0    s0, CP0_CAUSE           # get irq bits
-       mfc0    s1, CP0_STATUS          # get irq mask
-       andi    s0, ST0_IM              # CAUSE.CE may be non-zero!
-       and     s0, s1
-
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-       .set    mips32
-       clz     a0, s0
-       .set    mips0
-       negu    a0
-       addu    a0, 31-CAUSEB_IP
-       bltz    a0, spurious
-#else
-       beqz    s0, spurious
-        li     a0, 7
-
-       and     t0, s0, 0xf000
-       sltiu   t0, t0, 1
-       sll     t0, 2
-       subu    a0, t0
-       sll     s0, t0
-
-       and     t0, s0, 0xc000
-       sltiu   t0, t0, 1
-       sll     t0, 1
-       subu    a0, t0
-       sll     s0, t0
-
-       and     t0, s0, 0x8000
-       sltiu   t0, t0, 1
-       # sll   t0, 0
-       subu    a0, t0
-       # sll   s0, t0
-#endif
-
-        li     a1, MIPSCPU_INT_I8259A
-       bne     a0, a1, 1f
-        addu   a0, MIPSCPU_INT_BASE
-
-       jal     malta_hw0_irqdispatch
-        move    a0, sp
-
-       j       ret_from_irq
-        nop
-1:
-
-       jal     do_IRQ
-        move   a1, sp
-
-       j       ret_from_irq
-        nop
-
-spurious:
-       j       spurious_interrupt
-        nop
-       END(mipsIRQ)
index d06dc5a..1da8c18 100644 (file)
@@ -40,7 +40,6 @@
 #include <asm/mips-boards/msc01_pci.h>
 #include <asm/msc01_ic.h>
 
-extern asmlinkage void mipsIRQ(void);
 extern void mips_timer_interrupt(void);
 
 static DEFINE_SPINLOCK(mips_irq_lock);
@@ -114,7 +113,7 @@ static inline int get_int(void)
        return irq;
 }
 
-void malta_hw0_irqdispatch(struct pt_regs *regs)
+static void malta_hw0_irqdispatch(struct pt_regs *regs)
 {
        int irq;
 
@@ -182,6 +181,92 @@ void corehi_irqdispatch(struct pt_regs *regs)
         die("CoreHi interrupt", regs);
 }
 
+static inline int clz(unsigned long x)
+{
+       __asm__ (
+       "       .set    push                                    \n"
+       "       .set    mips32                                  \n"
+       "       clz     %0, %1                                  \n"
+       "       .set    pop                                     \n"
+       : "=r" (x)
+       : "r" (x));
+
+       return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+       return -clz(pending) + 31 - CAUSEB_IP;
+#else
+       unsigned int a0 = 7;
+       unsigned int t0;
+
+       t0 = s0 & 0xf000;
+       t0 = t0 < 1;
+       t0 = t0 << 2;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
+
+       t0 = s0 & 0xc000;
+       t0 = t0 < 1;
+       t0 = t0 << 1;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
+
+       t0 = s0 & 0x8000;
+       t0 = t0 < 1;
+       //t0 = t0 << 2;
+       a0 = a0 - t0;
+       //s0 = s0 << t0;
+
+       return a0;
+#endif
+}
+
+/*
+ * IRQs on the Malta board look basically (barring software IRQs which we
+ * don't use at all and all external interrupt sources are combined together
+ * on hardware interrupt 0 (MIPS IRQ 2)) like:
+ *
+ *     MIPS IRQ        Source
+ *      --------        ------
+ *             0       Software (ignored)
+ *             1        Software (ignored)
+ *             2        Combined hardware interrupt (hw0)
+ *             3        Hardware (ignored)
+ *             4        Hardware (ignored)
+ *             5        Hardware (ignored)
+ *             6        Hardware (ignored)
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ * Lowest  ----     Combined hardware interrupt
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+       int irq;
+
+       irq = irq_ffs(pending);
+
+       if (irq == MIPSCPU_INT_I8259A)
+               malta_hw0_irqdispatch(regs);
+       else if (irq > 0)
+               do_IRQ(MIPSCPU_INT_BASE + irq, regs);
+       else
+               spurious_interrupt(regs);
+}
+
 static struct irqaction i8259irq = {
        .handler = no_action,
        .name = "XT-PIC cascade"
@@ -214,7 +299,6 @@ int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t);
 
 void __init arch_init_irq(void)
 {
-       set_except_vector(0, mipsIRQ);
        init_i8259_irqs();
 
        if (!cpu_has_veic)
@@ -245,7 +329,6 @@ void __init arch_init_irq(void)
                setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
        }
        else {
-               set_except_vector(0, mipsIRQ);
                setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
                setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
        }
index 01780b6..224bb84 100644 (file)
@@ -23,4 +23,4 @@
 # under Linux.
 #
 
-obj-y          := sead_int.o sead-irq.o sead_setup.o
+obj-y          := sead_int.o sead_setup.o
diff --git a/arch/mips/mips-boards/sead/sead-irq.S b/arch/mips/mips-boards/sead/sead-irq.S
deleted file mode 100644 (file)
index d5dea1d..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Interrupt exception dispatch code.
- *
- */
-#include <linux/config.h>
-
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/mips-boards/seadint.h>
-
-/*
- * IRQs on the SEAD board look basically are combined together on hardware
- * interrupt 0 (MIPS IRQ 2)) like:
- *
- *     MIPS IRQ        Source
- *      --------        ------
- *             0       Software (ignored)
- *             1        Software (ignored)
- *             2        UART0 (hw0)
- *             3        UART1 (hw1)
- *             4        Hardware (ignored)
- *             5        Hardware (ignored)
- *             6        Hardware (ignored)
- *             7        R4k timer (what we use)
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ----     R4k Timer
- * Lowest  ----     Combined hardware interrupt
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
-       .text
-       .set    noreorder
-       .set    noat
-       .align  5
-       NESTED(mipsIRQ, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-       .set    at
-
-       mfc0    s0, CP0_CAUSE           # get irq bits
-       mfc0    s1, CP0_STATUS          # get irq mask
-       andi    s0, ST0_IM              # CAUSE.CE may be non-zero!
-       and     s0, s1
-
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-       .set    mips32
-       clz     a0, s0
-       .set    mips0
-       negu    a0
-       addu    a0, 31-CAUSEB_IP
-       bltz    a0, spurious
-#else
-       beqz    s0, spurious
-        li     a0, 7
-
-       and     t0, s0, 0xf000
-       sltiu   t0, t0, 1
-       sll     t0, 2
-       subu    a0, t0
-       sll     s0, t0
-
-       and     t0, s0, 0xc000
-       sltiu   t0, t0, 1
-       sll     t0, 1
-       subu    a0, t0
-       sll     s0, t0
-
-       and     t0, s0, 0x8000
-       sltiu   t0, t0, 1
-       # sll   t0, 0
-       subu    a0, t0
-       # sll   s0, t0
-#endif
-
-        addu   a0, MIPSCPU_INT_BASE
-       jal     do_IRQ
-        move   a1, sp
-
-       j       ret_from_irq
-        nop
-
-spurious:
-       j       spurious_interrupt
-        nop
-       END(mipsIRQ)
index 90fda0d..9168d93 100644 (file)
 #include <linux/irq.h>
 
 #include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
 #include <asm/system.h>
 
 #include <asm/mips-boards/seadint.h>
 
-extern asmlinkage void mipsIRQ(void);
+static inline int clz(unsigned long x)
+{
+       __asm__ (
+       "       .set    push                                    \n"
+       "       .set    mips32                                  \n"
+       "       clz     %0, %1                                  \n"
+       "       .set    pop                                     \n"
+       : "=r" (x)
+       : "r" (x));
+
+       return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+       return -clz(pending) + 31 - CAUSEB_IP;
+#else
+       unsigned int a0 = 7;
+       unsigned int t0;
+
+       t0 = s0 & 0xf000;
+       t0 = t0 < 1;
+       t0 = t0 << 2;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
+
+       t0 = s0 & 0xc000;
+       t0 = t0 < 1;
+       t0 = t0 << 1;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
+
+       t0 = s0 & 0x8000;
+       t0 = t0 < 1;
+       //t0 = t0 << 2;
+       a0 = a0 - t0;
+       //s0 = s0 << t0;
+
+       return a0;
+#endif
+}
+
+/*
+ * IRQs on the SEAD board look basically are combined together on hardware
+ * interrupt 0 (MIPS IRQ 2)) like:
+ *
+ *     MIPS IRQ        Source
+ *      --------        ------
+ *             0       Software (ignored)
+ *             1        Software (ignored)
+ *             2        UART0 (hw0)
+ *             3        UART1 (hw1)
+ *             4        Hardware (ignored)
+ *             5        Hardware (ignored)
+ *             6        Hardware (ignored)
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ * Lowest  ----     Combined hardware interrupt
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+       int irq;
+
+       irq = irq_ffs(pending);
+
+       if (irq >= 0)
+               do_IRQ(MIPSCPU_INT_BASE + irq, regs);
+       else
+               spurious_interrupt(regs);
+}
 
 void __init arch_init_irq(void)
 {
        mips_cpu_irq_init(MIPSCPU_INT_BASE);
-
-       /* Now safe to set the exception vector. */
-       set_except_vector(0, mipsIRQ);
 }
index a4d0a2c..2c15c8e 100644 (file)
 
 extern void mips_cpu_irq_init(int);
 
-extern asmlinkage void simIRQ(void);
+static inline int clz(unsigned long x)
+{
+       __asm__ (
+       "       .set    push                                    \n"
+       "       .set    mips32                                  \n"
+       "       clz     %0, %1                                  \n"
+       "       .set    pop                                     \n"
+       : "=r" (x)
+       : "r" (x));
+
+       return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+       return -clz(pending) + 31 - CAUSEB_IP;
+#else
+       unsigned int a0 = 7;
+       unsigned int t0;
+
+       t0 = s0 & 0xf000;
+       t0 = t0 < 1;
+       t0 = t0 << 2;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
+
+       t0 = s0 & 0xc000;
+       t0 = t0 < 1;
+       t0 = t0 << 1;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
 
-asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs)
+       t0 = s0 & 0x8000;
+       t0 = t0 < 1;
+       //t0 = t0 << 2;
+       a0 = a0 - t0;
+       //s0 = s0 << t0;
+
+       return a0;
+#endif
+}
+
+static inline void sim_hw0_irqdispatch(struct pt_regs *regs)
 {
        do_IRQ(2, regs);
 }
 
-void __init arch_init_irq(void)
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 {
-       /* Now safe to set the exception vector. */
-       set_except_vector(0, simIRQ);
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+       int irq;
+
+       irq = irq_ffs(pending);
 
+       if (irq > 0)
+               do_IRQ(MIPSCPU_INT_BASE + irq, regs);
+       else
+               spurious_interrupt(regs);
+}
+
+void __init arch_init_irq(void)
+{
        mips_cpu_irq_init(MIPSCPU_INT_BASE);
 }
index 20bbd3e..67372f3 100644 (file)
@@ -6,7 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-obj-y += int-handler.o irq.o prom.o reset.o setup.o
+obj-y += irq.o prom.o reset.o setup.o
 
 obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o
 obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
diff --git a/arch/mips/momentum/jaguar_atx/int-handler.S b/arch/mips/momentum/jaguar_atx/int-handler.S
deleted file mode 100644 (file)
index 55bc789..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Based on work:
- *   Copyright 2001 MontaVista Software Inc.
- *   Author: jsun@mvista.com or jsun@junsun.net
- *
- * First-level interrupt dispatcher for Jaguar-ATX board.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * First level interrupt dispatcher for Ocelot-CS board
- */
-               .align  5
-               NESTED(jaguar_handle_int, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-               mfc0    t0, CP0_CAUSE
-               mfc0    t2, CP0_STATUS
-
-               and     t0, t2
-
-               andi    t1, t0, STATUSF_IP0     /* sw0 software interrupt */
-               bnez    t1, ll_sw0_irq
-               andi    t1, t0, STATUSF_IP1     /* sw1 software interrupt */
-               bnez    t1, ll_sw1_irq
-               andi    t1, t0, STATUSF_IP2     /* int0 hardware line */
-               bnez    t1, ll_pcixa_irq
-               andi    t1, t0, STATUSF_IP3     /* int1 hardware line */
-               bnez    t1, ll_pcixb_irq
-               andi    t1, t0, STATUSF_IP4     /* int2 hardware line */
-               bnez    t1, ll_pcia_irq
-               andi    t1, t0, STATUSF_IP5     /* int3 hardware line */
-               bnez    t1, ll_pcib_irq
-               andi    t1, t0, STATUSF_IP6     /* int4 hardware line */
-               bnez    t1, ll_uart_irq
-               andi    t1, t0, STATUSF_IP7     /* cpu timer */
-               bnez    t1, ll_cputimer_irq
-
-               nop
-               nop
-
-               /* now look at extended interrupts */
-               mfc0    t0, CP0_CAUSE
-               cfc0    t1, CP0_S1_INTCONTROL
-
-               /* shift the mask 8 bits left to line up the bits */
-               sll     t2, t1, 8
-
-               and     t0, t2
-               srl     t0, t0, 16
-
-               andi    t1, t0, STATUSF_IP8     /* int6 hardware line */
-               bnez    t1, ll_mv64340_decode_irq
-
-               nop
-               nop
-
-               .set    reorder
-
-               /* wrong alarm or masked ... */
-               j       spurious_interrupt
-               nop
-               END(jaguar_handle_int)
-
-               .align  5
-ll_sw0_irq:
-               li      a0, 0
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-ll_sw1_irq:
-               li      a0, 1
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-ll_pcixa_irq:
-               li      a0, 2
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pcixb_irq:
-               li      a0, 3
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pcia_irq:
-               li      a0, 4
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pcib_irq:
-               li      a0, 5
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_uart_irq:
-               li      a0, 6
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_cputimer_irq:
-               li      a0, 7
-               move    a1, sp
-               jal     ll_timer_interrupt
-               j       ret_from_irq
-
-ll_mv64340_decode_irq:
-               move    a0, sp
-               jal     ll_mv64340_irq
-               j       ret_from_irq
index 15588f9..ec4032b 100644 (file)
@@ -10,7 +10,7 @@
  *   Copyright 2001 MontaVista Software Inc.
  *   Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
- *   Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *   Copyright (C) 2000, 01, 06 Ralf Baechle (ralf@linux-mips.org)
  *
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
 #include <linux/types.h>
 #include <asm/irq_cpu.h>
 #include <asm/mipsregs.h>
+#include <asm/time.h>
 
-extern asmlinkage void jaguar_handle_int(void);
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status();
+
+       if (pending & STATUSF_IP0)
+               do_IRQ(0, regs);
+       else if (pending & STATUSF_IP1)
+               do_IRQ(1, regs);
+       else if (pending & STATUSF_IP2)
+               do_IRQ(2, regs);
+       else if (pending & STATUSF_IP3)
+               do_IRQ(3, regs);
+       else if (pending & STATUSF_IP4)
+               do_IRQ(4, regs);
+       else if (pending & STATUSF_IP5)
+               do_IRQ(5, regs);
+       else if (pending & STATUSF_IP6)
+               do_IRQ(6, regs);
+       else if (pending & STATUSF_IP7)
+               ll_timer_interrupt(7, regs);
+       else {
+               /*
+                * Now look at the extended interrupts
+                */
+               pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
+               if (pending & STATUSF_IP8)
+                       ll_mv64340_irq(regs);
+       }
+}
 
 static struct irqaction cascade_mv64340 = {
        no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
@@ -53,8 +82,6 @@ void __init arch_init_irq(void)
         */
        clear_c0_status(ST0_IM);
 
-       /* Sets the first-level interrupt dispatcher. */
-       set_except_vector(0, jaguar_handle_int);
        mips_cpu_irq_init(0);
        rm7k_cpu_irq_init(8);
 
index aab8fd8..8bcea64 100644 (file)
@@ -5,4 +5,4 @@
 # removes any old dependencies. DON'T put your own dependencies here
 # unless it's something special (ie not a .c file).
 #
-obj-y   += int-handler.o irq.o prom.o reset.o setup.o
+obj-y   += irq.o prom.o reset.o setup.o
diff --git a/arch/mips/momentum/ocelot_3/int-handler.S b/arch/mips/momentum/ocelot_3/int-handler.S
deleted file mode 100644 (file)
index b120726..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * Copyright 2004 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Manish Lachwani, mlachwani@mvista.com
- *
- * First-level interrupt dispatcher for Ocelot-3 board.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * First level interrupt dispatcher for Ocelot-3 board
- */
-               .align  5
-               NESTED(ocelot3_handle_int, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-
-               mfc0    t0, CP0_CAUSE
-               mfc0    t2, CP0_STATUS
-
-               and     t0, t2
-
-               andi    t1, t0, STATUSF_IP0     /* sw0 software interrupt (IRQ0) */
-               bnez    t1, ll_sw0_irq
-
-               andi    t1, t0, STATUSF_IP1     /* sw1 software interrupt (IRQ1) */
-               bnez    t1, ll_sw1_irq
-
-               andi    t1, t0, STATUSF_IP2     /* int0 hardware line (IRQ2) */
-               bnez    t1, ll_pci0slot1_irq
-
-               andi    t1, t0, STATUSF_IP3     /* int1 hardware line (IRQ3) */
-               bnez    t1, ll_pci0slot2_irq
-
-               andi    t1, t0, STATUSF_IP4     /* int2 hardware line (IRQ4) */
-               bnez    t1, ll_pci1slot1_irq
-
-               andi    t1, t0, STATUSF_IP5     /* int3 hardware line (IRQ5) */
-               bnez    t1, ll_pci1slot2_irq
-
-               andi    t1, t0, STATUSF_IP6     /* int4 hardware line (IRQ6) */
-               bnez    t1, ll_uart_irq
-
-               andi    t1, t0, STATUSF_IP7     /* cpu timer (IRQ7) */
-               bnez    t1, ll_cputimer_irq
-
-                /* now look at extended interrupts */
-                mfc0    t0, CP0_CAUSE
-                cfc0    t1, CP0_S1_INTCONTROL
-
-                /* shift the mask 8 bits left to line up the bits */
-                sll     t2, t1, 8
-
-                and     t0, t2
-                srl     t0, t0, 16
-
-                andi    t1, t0, STATUSF_IP8     /* int6 hardware line (IRQ9) */
-                bnez    t1, ll_mv64340_decode_irq
-
-               .set    reorder
-
-               /* wrong alarm or masked ... */
-               jal     spurious_interrupt
-               nop
-               j       ret_from_irq
-                nop
-               END(ocelot3_handle_int)
-
-               .align  5
-ll_sw0_irq:
-               li      a0, 0           /* IRQ 1 */
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-ll_sw1_irq:
-               li      a0, 1           /* IRQ 2 */
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pci0slot1_irq:
-               li      a0, 2           /* IRQ 3 */
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pci0slot2_irq:
-               li      a0, 3           /* IRQ 4 */
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pci1slot1_irq:
-               li      a0, 4           /* IRQ 5 */
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pci1slot2_irq:
-               li      a0, 5           /* IRQ 6 */
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_uart_irq:
-               li      a0, 6           /* IRQ 7 */
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_cputimer_irq:
-               li      a0, 7           /* IRQ 8 */
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_mv64340_decode_irq:
-               move    a0, sp
-               jal     ll_mv64340_irq
-               j       ret_from_irq
-
index 42464db..87c63c3 100644 (file)
@@ -53,8 +53,6 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-extern asmlinkage void ocelot3_handle_int(void);
-
 static struct irqaction cascade_mv64340 = {
        no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
 };
@@ -67,9 +65,6 @@ void __init arch_init_irq(void)
         */
        clear_c0_status(ST0_IM | ST0_BEV);
 
-       /* Sets the first-level interrupt dispatcher. */
-       set_except_vector(0, ocelot3_handle_int);
-       mips_cpu_irq_init(0);
        rm7k_cpu_irq_init(8);
 
        /* set up the cascading interrupts */
@@ -79,3 +74,36 @@ void __init arch_init_irq(void)
        set_c0_status(ST0_IM); /* IE in the status register */
 
 }
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status();
+
+       if (pending & STATUSF_IP0)
+               do_IRQ(0, regs);
+       else if (pending & STATUSF_IP1)
+               do_IRQ(1, regs);
+       else if (pending & STATUSF_IP2)
+               do_IRQ(2, regs);
+       else if (pending & STATUSF_IP3)
+               do_IRQ(3, regs);
+       else if (pending & STATUSF_IP4)
+               do_IRQ(4, regs);
+       else if (pending & STATUSF_IP5)
+               do_IRQ(5, regs);
+       else if (pending & STATUSF_IP6)
+               do_IRQ(6, regs);
+       else if (pending & STATUSF_IP7)
+               do_IRQ(7, regs);
+       else {
+               /*
+                * Now look at the extended interrupts
+                */
+               pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
+
+               if (pending & STATUSF_IP8)
+                       ll_mv64340_irq(regs);
+               else
+                       spurious_interrupt(regs);
+       }
+}
index 9124077..94802b4 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for Momentum Computer's Ocelot-C and -CS boards.
 #
 
-obj-y                  += cpci-irq.o int-handler.o irq.o prom.o reset.o \
+obj-y                  += cpci-irq.o irq.o prom.o reset.o \
                           setup.o uart-irq.o
 
 obj-$(CONFIG_KGDB)     += dbg_io.o
diff --git a/arch/mips/momentum/ocelot_c/int-handler.S b/arch/mips/momentum/ocelot_c/int-handler.S
deleted file mode 100644 (file)
index f778341..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * First-level interrupt dispatcher for Ocelot-CS board.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include "ocelot_c_fpga.h"
-
-/*
- * First level interrupt dispatcher for Ocelot-CS board
- */
-               .align  5
-               NESTED(ocelot_handle_int, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-               mfc0    t0, CP0_CAUSE
-               mfc0    t2, CP0_STATUS
-
-               and     t0, t2
-
-               andi    t1, t0, STATUSF_IP0     /* sw0 software interrupt */
-               bnez    t1, ll_sw0_irq
-               andi    t1, t0, STATUSF_IP1     /* sw1 software interrupt */
-               bnez    t1, ll_sw1_irq
-               andi    t1, t0, STATUSF_IP2     /* int0 hardware line */
-               bnez    t1, ll_scsi_irq
-               andi    t1, t0, STATUSF_IP3     /* int1 hardware line */
-               bnez    t1, ll_uart_decode_irq
-               andi    t1, t0, STATUSF_IP4     /* int2 hardware line */
-               bnez    t1, ll_pmc_irq
-               andi    t1, t0, STATUSF_IP5     /* int3 hardware line */
-               bnez    t1, ll_cpci_decode_irq
-               andi    t1, t0, STATUSF_IP6     /* int4 hardware line */
-               bnez    t1, ll_mv64340_decode_irq
-               andi    t1, t0, STATUSF_IP7     /* cpu timer */
-               bnez    t1, ll_cputimer_irq
-
-               .set    reorder
-
-               /* wrong alarm or masked ... */
-               jal     spurious_interrupt
-               nop
-               j       ret_from_irq
-               END(ocelot_handle_int)
-
-               .align  5
-ll_sw0_irq:
-               li      a0, 0
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-ll_sw1_irq:
-               li      a0, 1
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-ll_scsi_irq:
-               li      a0, 2
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_uart_decode_irq:
-               move    a0, sp
-               jal     ll_uart_irq
-               j       ret_from_irq
-
-ll_pmc_irq:
-               li      a0, 4
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_cpci_decode_irq:
-               move    a0, sp
-               jal     ll_cpci_irq
-               j       ret_from_irq
-
-ll_mv64340_decode_irq:
-               move    a0, sp
-               jal     ll_mv64340_irq
-               j       ret_from_irq
-
-ll_cputimer_irq:
-               li      a0, 7
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
index a5764bc..86f61ce 100644 (file)
@@ -48,7 +48,6 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-extern asmlinkage void ocelot_handle_int(void);
 extern void uart_irq_init(void);
 extern void cpci_irq_init(void);
 
@@ -60,6 +59,33 @@ static struct irqaction cascade_mv64340 = {
        no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL
 };
 
+extern void ll_uart_irq(struct pt_regs *regs);
+extern void ll_cpci_irq(struct pt_regs *regs);
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status();
+
+       if (pending & STATUSF_IP0)
+               do_IRQ(0, regs);
+       else if (pending & STATUSF_IP1)
+               do_IRQ(1, regs);
+       else if (pending & STATUSF_IP2)
+               do_IRQ(2, regs);
+       else if (pending & STATUSF_IP3)
+               ll_uart_irq(regs);
+       else if (pending & STATUSF_IP4)
+               do_IRQ(4, regs);
+       else if (pending & STATUSF_IP5)
+               ll_cpci_irq(regs);
+       else if (pending & STATUSF_IP6)
+               ll_mv64340_irq(regs);
+       else if (pending & STATUSF_IP7)
+               do_IRQ(7, regs);
+       else
+               spurious_interrupt(regs);
+}
+
 void __init arch_init_irq(void)
 {
        /*
@@ -68,8 +94,6 @@ void __init arch_init_irq(void)
         */
        clear_c0_status(ST0_IM);
 
-       /* Sets the first-level interrupt dispatcher. */
-       set_except_vector(0, ocelot_handle_int);
        mips_cpu_irq_init(0);
 
        /* set up the cascading interrupts */
index e5f1cb0..adb5665 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for Momentum Computer's Ocelot-G board.
 #
 
-obj-y                  += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o
+obj-y                  += irq.o gt-irq.o prom.o reset.o setup.o
 obj-$(CONFIG_KGDB)     += dbg_io.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/momentum/ocelot_g/int-handler.S b/arch/mips/momentum/ocelot_g/int-handler.S
deleted file mode 100644 (file)
index 772e8f7..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * First-level interrupt dispatcher for ocelot board.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * first level interrupt dispatcher for ocelot board -
- * We check for the timer first, then check PCI ints A and D.
- * Then check for serial IRQ and fall through.
- */
-               .align  5
-               NESTED(ocelot_handle_int, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-               mfc0    t0, CP0_CAUSE
-               mfc0    t2, CP0_STATUS
-
-               and     t0, t2
-
-                andi   t1, t0, STATUSF_IP2     /* int0 hardware line */
-               bnez    t1, ll_pri_enet_irq
-                andi   t1, t0, STATUSF_IP3     /* int1 hardware line */
-               bnez    t1, ll_sec_enet_irq
-                andi   t1, t0, STATUSF_IP4     /* int2 hardware line */
-               bnez    t1, ll_uart_irq
-                andi   t1, t0, STATUSF_IP5     /* int3 hardware line */
-               bnez    t1, ll_cpci_irq
-                andi   t1, t0, STATUSF_IP6     /* int4 hardware line */
-               bnez    t1, ll_galileo_p0_irq
-                andi   t1, t0, STATUSF_IP7     /* cpu timer */
-               bnez    t1, ll_cputimer_irq
-
-                /* now look at the extended interrupts */
-               mfc0    t0, CP0_CAUSE
-               cfc0    t1, CP0_S1_INTCONTROL
-
-               /* shift the mask 8 bits left to line up the bits */
-                sll    t2, t1, 8
-
-                and    t0, t2
-                srl    t0, t0, 16
-
-                andi   t1, t0, STATUSF_IP8     /* int6 hardware line */
-               bnez    t1, ll_galileo_p1_irq
-                andi   t1, t0, STATUSF_IP9     /* int7 hardware line */
-               bnez    t1, ll_pmc_irq
-                andi   t1, t0, STATUSF_IP10    /* int8 hardware line */
-               bnez    t1, ll_cpci_abcd_irq
-                andi   t1, t0, STATUSF_IP11    /* int9 hardware line */
-               bnez    t1, ll_testpoint_irq
-
-               .set    reorder
-
-               /* wrong alarm or masked ... */
-               j       spurious_interrupt
-               nop
-               END(ocelot_handle_int)
-
-               .align  5
-ll_pri_enet_irq:
-               li      a0, 2
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_sec_enet_irq:
-               li      a0, 3
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_uart_irq:
-               li      a0, 4
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_cpci_irq:
-               li      a0, 5
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_galileo_p0_irq:
-               li      a0, 6
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_cputimer_irq:
-               li      a0, 7
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_galileo_p1_irq:
-               li      a0, 8
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_pmc_irq:
-               li      a0, 9
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_cpci_abcd_irq:
-               li      a0, 10
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_testpoint_irq:
-               li      a0, 11
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
index 5eb85b1..7a4a419 100644 (file)
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-extern asmlinkage void ocelot_handle_int(void);
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status();
+
+       if (pending & STATUSF_IP2)
+               do_IRQ(2, regs);
+       else if (pending & STATUSF_IP3)
+               do_IRQ(3, regs);
+       else if (pending & STATUSF_IP4)
+               do_IRQ(4, regs);
+       else if (pending & STATUSF_IP5)
+               do_IRQ(5, regs);
+       else if (pending & STATUSF_IP6)
+               do_IRQ(6, regs);
+       else if (pending & STATUSF_IP7)
+               do_IRQ(7, regs);
+       else {
+               /*
+                * Now look at the extended interrupts
+                */
+               pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
+
+               if (pending & STATUSF_IP8)
+                       do_IRQ(8, regs);
+               else if (pending & STATUSF_IP9)
+                       do_IRQ(9, regs);
+               else if (pending & STATUSF_IP10)
+                       do_IRQ(10, regs);
+               else if (pending & STATUSF_IP11)
+                       do_IRQ(11, regs);
+               else
+                       spurious_interrupt(regs);
+       }
+}
+
 extern void gt64240_irq_init(void);
 
 void __init arch_init_irq(void)
@@ -60,8 +94,6 @@ void __init arch_init_irq(void)
        clear_c0_status(ST0_IM);
        local_irq_disable();
 
-       /* Sets the first-level interrupt dispatcher. */
-       set_except_vector(0, ocelot_handle_int);
        mips_cpu_irq_init(0);
        rm7k_cpu_irq_init(8);
 
index 6e38f3b..b7c6381 100644 (file)
@@ -22,6 +22,6 @@
 # under Linux.
 #
 
-obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o
+obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_KGDB) += gdb_hook.o
index c500e2d..39ee631 100644 (file)
@@ -38,8 +38,6 @@
 #include <int.h>
 #include <uart.h>
 
-extern asmlinkage void cp0_irqdispatch(void);
-
 static DEFINE_SPINLOCK(irq_lock);
 
 /* default prio for interrupts */
@@ -55,7 +53,7 @@ static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
        1                       //  70
 };
 
-void hw0_irqdispatch(int irq, struct pt_regs *regs)
+static void hw0_irqdispatch(int irq, struct pt_regs *regs)
 {
        /* find out which interrupt */
        irq = PNX8550_GIC_VECTOR_0 >> 3;
@@ -68,7 +66,7 @@ void hw0_irqdispatch(int irq, struct pt_regs *regs)
 }
 
 
-void timer_irqdispatch(int irq, struct pt_regs *regs)
+static void timer_irqdispatch(int irq, struct pt_regs *regs)
 {
        irq = (0x01c0 & read_c0_config7()) >> 6;
 
@@ -88,6 +86,20 @@ void timer_irqdispatch(int irq, struct pt_regs *regs)
        }
 }
 
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_status() & read_c0_cause();
+
+       if (pending & STATUSF_IP2)
+               do_IRQ(2, regs);
+       else if (pending & STATUSF_IP7) {
+               if (read_c0_config7() & 0x01c0)
+                       timer_irqdispatch(7, regs);
+       }
+
+       spurious_interrupt(regs);
+}
+
 static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
 {
        unsigned long status = read_c0_status();
@@ -223,9 +235,6 @@ void __init arch_init_irq(void)
        int i;
        int configPR;
 
-       /* init of cp0 interrupts */
-       set_except_vector(0, cp0_irqdispatch);
-
        for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
                irq_desc[i].handler = &level_irq_type;
                pnx8550_ack(i); /* mask the irq just in case  */
diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S
deleted file mode 100644 (file)
index e049a71..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2002 Philips, Inc. All rights.
- * Copyright (c) 2002 Red Hat, Inc. All rights.
- *
- * This software may be freely redistributed under the terms of the
- * GNU General Public License.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Based upon arch/mips/galileo-boards/ev64240/int-handler.S
- *
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * cp0_irqdispatch
- *
- *    Code to handle in-core interrupt exception.
- */
-
-               .align  5
-               .set    reorder
-               .set    noat
-               NESTED(cp0_irqdispatch, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-               mfc0    t0,CP0_CAUSE
-               mfc0    t2,CP0_STATUS
-
-               and     t0,t2
-
-               andi    t1,t0,STATUSF_IP2 /* int0 hardware line */
-               bnez    t1,ll_hw0_irq
-               nop
-
-               andi    t1,t0,STATUSF_IP7 /* int5 hardware line */
-               bnez    t1,ll_timer_irq
-               nop
-
-               /* wrong alarm or masked ... */
-
-               jal     spurious_interrupt
-               nop
-               j       ret_from_irq
-               END(cp0_irqdispatch)
-
-               .align  5
-               .set    reorder
-ll_hw0_irq:
-               li      a0,2
-               move    a1,sp
-               jal     hw0_irqdispatch
-               nop
-               j       ret_from_irq
-               nop
-
-               .align  5
-               .set    reorder
-ll_timer_irq:
-               mfc0    t3,CP0_CONFIG,7
-               andi    t4,t3,0x01c0
-               beqz    t4,ll_timer_out
-               nop
-               li      a0,7
-               move    a1,sp
-               jal     timer_irqdispatch
-               nop
-
-ll_timer_out:  j       ret_from_irq
-               nop
index ae96a71..e931e0d 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the PMC-Sierra Titan
 #
 
-obj-y    += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o
+obj-y    += irq.o i2c-yosemite.o prom.o py-console.o setup.o
 
 obj-$(CONFIG_KGDB)             += dbg_io.o
 obj-$(CONFIG_SMP)              += smp.o
diff --git a/arch/mips/pmc-sierra/yosemite/irq-handler.S b/arch/mips/pmc-sierra/yosemite/irq-handler.S
deleted file mode 100644 (file)
index 33b9c40..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2003, 04 PMC-Sierra Inc.
- * Author: Manish Lachwani (lachwani@pmc-sierra.com
- * Copyright 2004 Ralf Baechle (ralf@linux-mips.org)
- *
- * First-level interrupt router for the PMC-Sierra Titan board
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * Titan supports Hypertransport or PCI but not both. Hence, one interrupt
- * line is shared between the PCI slot A and Hypertransport. This is the
- * Processor INTB #0.
- */
-
-#include <linux/config.h>
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-               .align  5
-               NESTED(titan_handle_int, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-               .set    noreorder
-               la      ra, ret_from_irq
-               mfc0    t0, CP0_CAUSE
-               mfc0    t2, CP0_STATUS
-
-               and     t0, t2
-
-               andi    t2, t0, STATUSF_IP7     /* INTB5 hardware line */
-               bnez    t2, ll_timer_irq        /* Timer */
-               andi    t1, t0, STATUSF_IP2     /* INTB0 hardware line */
-               bnez    t1, ll_pcia_irq         /* 64-bit PCI */
-               andi    t2, t0, STATUSF_IP3     /* INTB1 hardware line */
-               bnez    t2, ll_pcib_irq         /* second 64-bit PCI slot */
-               andi    t1, t0, STATUSF_IP4     /* INTB2 hardware line */
-               bnez    t1, ll_duart_irq        /* UART */
-               andi    t2, t0, STATUSF_IP5     /* SMP inter-core interrupts */
-               bnez    t2, ll_smp_irq
-               andi    t1, t0, STATUSF_IP6
-               bnez    t1, ll_ht_irq           /* Hypertransport */
-
-               move    a0, sp
-               j       do_extended_irq
-               END(titan_handle_int)
-
-               .set    reorder
-               .align  5
-
-ll_pcia_irq:
-               li      a0, 2
-               move    a1, sp
-#ifdef CONFIG_HYPERTRANSPORT
-               j       ll_ht_smp_irq_handler
-#else
-               j       do_IRQ
-#endif
-
-ll_pcib_irq:
-               li      a0, 3
-               move    a1, sp
-               j       do_IRQ
-
-ll_duart_irq:
-               li      a0, 4
-               move    a1, sp
-               j       do_IRQ
-
-ll_smp_irq:
-               li      a0, 5
-               move    a1, sp
-#ifdef CONFIG_SMP
-               j       titan_mailbox_irq
-#else
-               j       do_IRQ
-#endif
-
-ll_ht_irq:
-               li      a0, 6
-               move    a1, sp
-               j       ll_ht_smp_irq_handler
-
-ll_timer_irq:
-               li      a0, 7
-               move    a1, sp
-               j       do_IRQ
index f4e2897..a1f524f 100644 (file)
@@ -2,6 +2,8 @@
  * Copyright (C) 2003 PMC-Sierra Inc.
  * Author: Manish Lachwani (lachwani@pmc-sierra.com)
  *
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ *
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
  *  Free Software Foundation;  either version 2 of the  License, or (at your
@@ -55,7 +57,6 @@
 #define HYPERTRANSPORT_INTC     0x7a           /* INTC# */
 #define HYPERTRANSPORT_INTD     0x7b           /* INTD# */
 
-extern asmlinkage void titan_handle_int(void);
 extern void jaguar_mailbox_irq(struct pt_regs *);
 
 /*
@@ -125,6 +126,35 @@ asmlinkage void do_extended_irq(struct pt_regs *regs)
 
 }
 
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int cause = read_c0_cause();
+       unsigned int status = read_c0_status();
+       unsigned int pending = cause & status;
+
+       if (pending & STATUSF_IP7) {
+               do_IRQ(7, regs);
+       } else if (pending & STATUSF_IP2) {
+#ifdef CONFIG_HYPERTRANSPORT
+               ll_ht_smp_irq_handler(2, regs);
+#else
+               do_IRQ(2, regs);
+#endif
+       } else if (pending & STATUSF_IP3) {
+               do_IRQ(3, regs);
+       } else if (pending & STATUSF_IP4) {
+               do_IRQ(4, regs);
+       } else if (pending & STATUSF_IP5) {
+#ifdef CONFIG_SMP
+               titan_mailbox_irq(regs);
+#else
+               do_IRQ(5, regs);
+#endif
+       } else if (pending & STATUSF_IP6) {
+               do_IRQ(4, regs);
+       }
+}
+
 #ifdef CONFIG_KGDB
 extern void init_second_port(void);
 #endif
@@ -136,7 +166,6 @@ void __init arch_init_irq(void)
 {
        clear_c0_status(ST0_IM);
 
-       set_except_vector(0, titan_handle_int);
        mips_cpu_irq_init(0);
        rm7k_cpu_irq_init(8);
        rm9k_cpu_irq_init(12);
index 6a8e8bc..730f459 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for Qemu specific kernel interface routines under Linux.
 #
 
-obj-y          = q-firmware.o q-int.o q-irq.o q-mem.o q-setup.o
+obj-y          = q-firmware.o q-irq.o q-mem.o q-setup.o
 
 obj-$(CONFIG_SMP) += q-smp.o
diff --git a/arch/mips/qemu/q-int.S b/arch/mips/qemu/q-int.S
deleted file mode 100644 (file)
index 6e3dfe5..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Qemu interrupt handler code.
- *
- * Copyright (C) 2005 by Ralf Baechle
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-       .align  5
-       NESTED(qemu_handle_int, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-       move    a0, sp
-       PTR_LA  ra, ret_from_irq
-       j       do_qemu_int
-       END(qemu_handle_int)
index 2c4e070..3352374 100644 (file)
@@ -9,7 +9,7 @@
 
 extern asmlinkage void qemu_handle_int(void);
 
-asmlinkage void do_qemu_int(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 {
        unsigned int pending = read_c0_status() & read_c0_cause();
 
@@ -29,7 +29,6 @@ asmlinkage void do_qemu_int(struct pt_regs *regs)
 
 void __init arch_init_irq(void)
 {
-       set_except_vector(0, qemu_handle_int);
        mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK;             /* 100MHz */
 
        init_i8259_irqs();
index eb0820f..6aa4c0c 100644 (file)
@@ -3,7 +3,7 @@
 # under Linux.
 #
 
-obj-y  += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \
+obj-y  += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \
           ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o
 
 obj-$(CONFIG_EISA)     += ip22-eisa.o
index d16fb43..fc6a7e2 100644 (file)
@@ -37,7 +37,6 @@ static char lc1msk_to_irqnr[256];
 static char lc2msk_to_irqnr[256];
 static char lc3msk_to_irqnr[256];
 
-extern asmlinkage void indyIRQ(void);
 extern int ip22_eisa_init(void);
 
 static void enable_local0_irq(unsigned int irq)
@@ -224,7 +223,7 @@ static struct hw_interrupt_type ip22_local3_irq_type = {
        .end            = end_local3_irq,
 };
 
-void indy_local0_irqdispatch(struct pt_regs *regs)
+static void indy_local0_irqdispatch(struct pt_regs *regs)
 {
        u8 mask = sgint->istat0 & sgint->imask0;
        u8 mask2;
@@ -242,7 +241,7 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
        return;
 }
 
-void indy_local1_irqdispatch(struct pt_regs *regs)
+static void indy_local1_irqdispatch(struct pt_regs *regs)
 {
        u8 mask = sgint->istat1 & sgint->imask1;
        u8 mask2;
@@ -262,7 +261,7 @@ void indy_local1_irqdispatch(struct pt_regs *regs)
 
 extern void ip22_be_interrupt(int irq, struct pt_regs *regs);
 
-void indy_buserror_irq(struct pt_regs *regs)
+static void indy_buserror_irq(struct pt_regs *regs)
 {
        int irq = SGI_BUSERR_IRQ;
 
@@ -307,6 +306,56 @@ static struct irqaction map1_cascade = {
 #define SGI_INTERRUPTS SGINT_LOCAL3
 #endif
 
+extern void indy_r4k_timer_interrupt(struct pt_regs *regs);
+extern void indy_8254timer_irq(struct pt_regs *regs);
+
+/*
+ * IRQs on the INDY look basically (barring software IRQs which we don't use
+ * at all) like:
+ *
+ *     MIPS IRQ        Source
+ *      --------        ------
+ *             0       Software (ignored)
+ *             1        Software (ignored)
+ *             2        Local IRQ level zero
+ *             3        Local IRQ level one
+ *             4        8254 Timer zero
+ *             5        8254 Timer one
+ *             6        Bus Error
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ *                  Local IRQ zero
+ *                  Local IRQ one
+ *                  Bus Error
+ *                  8254 Timer zero
+ * Lowest  ----     8254 Timer one
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause();
+
+       /*
+        * First we check for r4k counter/timer IRQ.
+        */
+       if (pending & CAUSEF_IP7)
+               indy_r4k_timer_interrupt(regs);
+       else if (pending & CAUSEF_IP2)
+               indy_local0_irqdispatch(regs);
+       else if (pending & CAUSEF_IP3)
+               indy_local1_irqdispatch(regs);
+       else if (pending & CAUSEF_IP6)
+               indy_buserror_irq(regs);
+       else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
+               indy_8254timer_irq(regs);
+}
+
 extern void mips_cpu_irq_init(unsigned int irq_base);
 
 void __init arch_init_irq(void)
@@ -369,8 +418,6 @@ void __init arch_init_irq(void)
        sgint->cmeimask0 = 0;
        sgint->cmeimask1 = 0;
 
-       set_except_vector(0, indyIRQ);
-
        /* init CPU irqs */
        mips_cpu_irq_init(SGINT_CPU);
 
diff --git a/arch/mips/sgi-ip22/ip22-irq.S b/arch/mips/sgi-ip22/ip22-irq.S
deleted file mode 100644 (file)
index 6ccbd9e..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * ip22-irq.S: Interrupt exception dispatch code for FullHouse and
- *             Guiness.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/* A lot of complication here is taken away because:
- *
- * 1) We handle one interrupt and return, sitting in a loop and moving across
- *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
- *    common case is one pending IRQ so optimize in that direction.
- *
- * 2) We need not check against bits in the status register IRQ mask, that
- *    would make this routine slow as hell.
- *
- * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
- *    between like BSD spl() brain-damage.
- *
- * Furthermore, the IRQs on the INDY look basically (barring software IRQs
- * which we don't use at all) like:
- *
- *     MIPS IRQ        Source
- *      --------        ------
- *             0       Software (ignored)
- *             1        Software (ignored)
- *             2        Local IRQ level zero
- *             3        Local IRQ level one
- *             4        8254 Timer zero
- *             5        8254 Timer one
- *             6        Bus Error
- *             7        R4k timer (what we use)
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ----     R4k Timer
- *                  Local IRQ zero
- *                  Local IRQ one
- *                  Bus Error
- *                  8254 Timer zero
- * Lowest  ----     8254 Timer one
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
-       .text
-       .set    noreorder
-       .set    noat
-       .align  5
-       NESTED(indyIRQ, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-       .set    at
-       mfc0    s0, CP0_CAUSE           # get irq mask
-
-       /* First we check for r4k counter/timer IRQ. */
-       andi    a0, s0, CAUSEF_IP7
-       beq     a0, zero, 1f
-        andi   a0, s0, CAUSEF_IP2      # delay slot, check local level zero
-
-       /* Wheee, a timer interrupt. */
-       jal     indy_r4k_timer_interrupt
-        move   a0, sp                  # delay slot
-       j       ret_from_irq
-        nop                            # delay slot
-
-1:
-       beq     a0, zero, 1f
-        andi   a0, s0, CAUSEF_IP3      # delay slot, check local level one
-
-       /* Wheee, local level zero interrupt. */
-       jal     indy_local0_irqdispatch
-        move   a0, sp                  # delay slot
-
-       j       ret_from_irq
-        nop                            # delay slot
-
-1:
-       beq     a0, zero, 1f
-        andi   a0, s0, CAUSEF_IP6      # delay slot, check bus error
-
-       /* Wheee, local level one interrupt. */
-       jal     indy_local1_irqdispatch
-        move   a0, sp                  # delay slot
-       j       ret_from_irq
-        nop                            # delay slot
-
-1:
-       beq     a0, zero, 1f
-        andi   a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)       # delay slot
-
-       /* Wheee, an asynchronous bus error... */
-       jal     indy_buserror_irq
-        move   a0, sp                  # delay slot
-       j       ret_from_irq
-        nop                            # delay slot
-
-1:
-       /* Here by mistake? It is possible, that by the time we take
-        * the exception the IRQ pin goes low, so just leave if this
-        * is the case.
-        */
-       beq     a0, zero, 1f
-        nop                            # delay slot
-
-       /* Must be one of the 8254 timers... */
-       jal     indy_8254timer_irq
-        move   a0, sp                  # delay slot
-1:
-       j       ret_from_irq
-        nop                            # delay slot
-       END(indyIRQ)
index 4ba3407..686ba14 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the IP27 specific kernel interface routines under Linux.
 #
 
-obj-y  := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
+obj-y  := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o \
           ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \
           ip27-timer.o ip27-hubio.o ip27-xtalk.o
 
index 3210613..19f1512 100644 (file)
@@ -9,10 +9,6 @@ ip27-init.c:find_lbaord_real. DONE
 in irix?
 6. Investigate why things do not work without the setup_test() call
 being invoked on all nodes in ip27-memory.c.
-7. Too many CLIs in the locore handlers :
-For the low level handlers set up by set_except_vector(),
-__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
-investigate whether the code should do CLI, STI or KMODE.
 8. Too many do_page_faults invoked - investigate.
 9. start_thread must turn off UX64 ... and define tlb_refill_debug.
 10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
diff --git a/arch/mips/sgi-ip27/ip27-irq-glue.S b/arch/mips/sgi-ip27/ip27-irq-glue.S
deleted file mode 100644 (file)
index c304df7..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-       .text
-       .align  5
-NESTED(ip27_irq, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-
-       mfc0    s0, CP0_CAUSE
-       mfc0    t0, CP0_STATUS
-       and     s0, t0
-       move    a0, sp
-       PTR_LA  ra, ret_from_irq
-
-       /* First check for RT interrupt.  */
-       andi    t0, s0, CAUSEF_IP4
-       bnez    t0, ip4
-       andi    t0, s0, CAUSEF_IP2
-       bnez    t0, ip2
-       andi    t0, s0, CAUSEF_IP3
-       bnez    t0, ip3
-       andi    t0, s0, CAUSEF_IP5
-       bnez    t0, ip5
-       andi    t0, s0, CAUSEF_IP6
-       bnez    t0, ip6
-       j       ra
-
-ip2:   j       ip27_do_irq_mask0       # PI_INT_PEND_0 or CC_PEND_{A|B}
-ip3:   j       ip27_do_irq_mask1       # PI_INT_PEND_1
-ip4:   j       ip27_rt_timer_interrupt
-ip5:   j       ip27_prof_timer
-ip6:   j       ip27_hub_error
-
-       END(ip27_irq)
index 2854ac4..2e643d2 100644 (file)
@@ -130,7 +130,7 @@ static int ms1bit(unsigned long x)
  * Kanoj 05.13.00
  */
 
-void ip27_do_irq_mask0(struct pt_regs *regs)
+static void ip27_do_irq_mask0(struct pt_regs *regs)
 {
        int irq, swlevel;
        hubreg_t pend0, mask0;
@@ -171,7 +171,7 @@ void ip27_do_irq_mask0(struct pt_regs *regs)
        LOCAL_HUB_L(PI_INT_PEND0);
 }
 
-void ip27_do_irq_mask1(struct pt_regs *regs)
+static void ip27_do_irq_mask1(struct pt_regs *regs)
 {
        int irq, swlevel;
        hubreg_t pend1, mask1;
@@ -196,12 +196,12 @@ void ip27_do_irq_mask1(struct pt_regs *regs)
        LOCAL_HUB_L(PI_INT_PEND1);
 }
 
-void ip27_prof_timer(struct pt_regs *regs)
+static void ip27_prof_timer(struct pt_regs *regs)
 {
        panic("CPU %d got a profiling interrupt", smp_processor_id());
 }
 
-void ip27_hub_error(struct pt_regs *regs)
+static void ip27_hub_error(struct pt_regs *regs)
 {
        panic("CPU %d got a hub error interrupt", smp_processor_id());
 }
@@ -421,9 +421,26 @@ int __devinit request_bridge_irq(struct bridge_controller *bc)
        return irq;
 }
 
+extern void ip27_rt_timer_interrupt(struct pt_regs *regs);
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned long pending = read_c0_cause() & read_c0_status();
+
+       if (pending & CAUSEF_IP4)
+               ip27_rt_timer_interrupt(regs);
+       else if (pending & CAUSEF_IP2)  /* PI_INT_PEND_0 or CC_PEND_{A|B} */
+               ip27_do_irq_mask0(regs);
+       else if (pending & CAUSEF_IP3)  /* PI_INT_PEND_1 */
+               ip27_do_irq_mask1(regs);
+       else if (pending & CAUSEF_IP5)
+               ip27_prof_timer(regs);
+       else if (pending & CAUSEF_IP6)
+               ip27_hub_error(regs);
+}
+
 void __init arch_init_irq(void)
 {
-       set_except_vector(0, ip27_irq);
 }
 
 void install_ipi(void)
index 470898f..530bf84 100644 (file)
@@ -3,7 +3,7 @@
 # under Linux.
 #
 
-obj-y  += ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \
+obj-y  += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \
           crime.o ip32-memory.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sgi-ip32/ip32-irq-glue.S b/arch/mips/sgi-ip32/ip32-irq-glue.S
deleted file mode 100644 (file)
index 200924e..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Harald Koerfgen
- * Copyright (C) 2001 Keith M Wesolowski
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-#include <asm/stackframe.h>
-#include <asm/addrspace.h>
-
-               .text
-               .set    noreorder
-               .set    noat
-               .align  5
-               NESTED(ip32_handle_int, PT_SIZE, ra)
-               .set    noat
-               SAVE_ALL
-               CLI                     # TEST: interrupts should be off
-               .set    at
-               .set    noreorder
-
-               mfc0    s0,CP0_CAUSE
-
-               andi    t1, s0, IE_IRQ0
-               bnez    t1, handle_irq0
-                andi   t1, s0, IE_IRQ1
-               bnez    t1, handle_irq1
-                andi   t1, s0, IE_IRQ2
-               bnez    t1, handle_irq2
-                andi   t1, s0, IE_IRQ3
-               bnez    t1, handle_irq3
-                andi   t1, s0, IE_IRQ4
-               bnez    t1, handle_irq4
-                andi   t1, s0, IE_IRQ5
-               bnez    t1, handle_irq5
-                nop
-
-               /* Either someone has triggered the "software interrupts"
-                * or we lost an interrupt somehow.  Ignore it.
-                */
-               j       ret_from_irq
-                nop
-
-handle_irq0:
-               jal     ip32_irq0
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-handle_irq1:
-               jal     ip32_irq1
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-handle_irq2:
-               jal     ip32_irq2
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-handle_irq3:
-               jal     ip32_irq3
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-handle_irq4:
-               jal     ip32_irq4
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-handle_irq5:
-               jal     ip32_irq5
-               move    a0, sp
-               j       ret_from_irq
-                nop
-
-               END(ip32_handle_int)
index 2eb22d6..22a6df9 100644 (file)
@@ -130,8 +130,6 @@ struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
 struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
                        CPU_MASK_NONE, "CRIME CPU error", NULL, NULL };
 
-extern void ip32_handle_int(void);
-
 /*
  * For interrupts wired from a single device to the CPU.  Only the clock
  * uses this it seems, which is IRQ 0 and IP7.
@@ -503,7 +501,7 @@ static void ip32_unknown_interrupt(struct pt_regs *regs)
 
 /* CRIME 1.1 appears to deliver all interrupts to this one pin. */
 /* change this to loop over all edge-triggered irqs, exception masked out ones */
-void ip32_irq0(struct pt_regs *regs)
+static void ip32_irq0(struct pt_regs *regs)
 {
        uint64_t crime_int;
        int irq = 0;
@@ -520,31 +518,49 @@ void ip32_irq0(struct pt_regs *regs)
        do_IRQ(irq, regs);
 }
 
-void ip32_irq1(struct pt_regs *regs)
+static void ip32_irq1(struct pt_regs *regs)
 {
        ip32_unknown_interrupt(regs);
 }
 
-void ip32_irq2(struct pt_regs *regs)
+static void ip32_irq2(struct pt_regs *regs)
 {
        ip32_unknown_interrupt(regs);
 }
 
-void ip32_irq3(struct pt_regs *regs)
+static void ip32_irq3(struct pt_regs *regs)
 {
        ip32_unknown_interrupt(regs);
 }
 
-void ip32_irq4(struct pt_regs *regs)
+static void ip32_irq4(struct pt_regs *regs)
 {
        ip32_unknown_interrupt(regs);
 }
 
-void ip32_irq5(struct pt_regs *regs)
+static void ip32_irq5(struct pt_regs *regs)
 {
        ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs);
 }
 
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause();
+
+       if (likely(pending & IE_IRQ0))
+               ip32_irq0(regs);
+       else if (unlikely(pending & IE_IRQ1))
+               ip32_irq1(regs);
+       else if (unlikely(pending & IE_IRQ2))
+               ip32_irq2(regs);
+       else if (unlikely(pending & IE_IRQ3))
+               ip32_irq3(regs);
+       else if (unlikely(pending & IE_IRQ4))
+               ip32_irq4(regs);
+       else if (likely(pending & IE_IRQ5))
+               ip32_irq5(regs);
+}
+
 void __init arch_init_irq(void)
 {
        unsigned int irq;
@@ -556,7 +572,6 @@ void __init arch_init_irq(void)
        crime->soft_int = 0;
        mace->perif.ctrl.istat = 0;
        mace->perif.ctrl.imask = 0;
-       set_except_vector(0, ip32_handle_int);
 
        for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
                hw_irq_controller *controller;
index 538d5a5..7b36ff3 100644 (file)
@@ -1,4 +1,4 @@
-obj-y := setup.o irq.o irq_handler.o time.o
+obj-y := setup.o irq.o time.o
 
 obj-$(CONFIG_SMP)                      += smp.o
 
index 9cf7d71..e61760b 100644 (file)
@@ -187,9 +187,6 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
 #endif
 
 
-/* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */
-extern void bcm1480_irq_handler(void);
-
 /*****************************************************************************/
 
 static unsigned int startup_bcm1480_irq(unsigned int irq)
@@ -422,7 +419,6 @@ void __init arch_init_irq(void)
 #endif
        /* Enable necessary IPs, disable the rest */
        change_c0_status(ST0_IM, imask);
-       set_except_vector(0, bcm1480_irq_handler);
 
 #ifdef CONFIG_KGDB
        if (kgdb_flag) {
@@ -473,3 +469,76 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs)
 }
 
 #endif         /* CONFIG_KGDB */
+
+static inline int dclz(unsigned long long x)
+{
+       int lz;
+
+       __asm__ (
+       "       .set    push                                            \n"
+       "       .set    mips64                                          \n"
+       "       dclz    %0, %1                                          \n"
+       "       .set    pop                                             \n"
+       : "=r" (lz)
+       : "r" (x));
+
+       return lz;
+}
+
+extern void bcm1480_timer_interrupt(struct pt_regs *regs);
+extern void bcm1480_mailbox_interrupt(struct pt_regs *regs);
+extern void bcm1480_kgdb_interrupt(struct pt_regs *regs);
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending;
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+       /* Set compare to count to silence count/compare timer interrupts */
+       write_c0_compare(read_c0_count());
+#endif
+
+       pending = read_c0_cause();
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+       if (pending & CAUSEF_IP7)       /* Cpu performance counter interrupt */
+               sbprof_cpu_intr(exception_epc(regs));
+#endif
+
+       if (pending & CAUSEF_IP4)
+               bcm1480_timer_interrupt(regs);
+
+#ifdef CONFIG_SMP
+       if (pending & CAUSEF_IP3)
+               bcm1480_mailbox_interrupt(regs);
+#endif
+
+#ifdef CONFIG_KGDB
+       if (pending & CAUSEF_IP6)
+               bcm1480_kgdb_interrupt(regs);           /* KGDB (uart 1) */
+#endif
+
+       if (pending & CAUSEF_IP2) {
+               unsigned long long mask_h, mask_l;
+               unsigned long base;
+
+               /*
+                * Default...we've hit an IP[2] interrupt, which means we've
+                * got to check the 1480 interrupt registers to figure out what
+                * to do.  Need to detect which CPU we're on, now that
+                * smp_affinity is supported.
+                */
+               base = A_BCM1480_IMR_MAPPER(smp_processor_id());
+               mask_h = __raw_readq(
+                       IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
+               mask_l = __raw_readq(
+                       IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
+
+               if (!mask_h) {
+                       if (mask_h ^ 1)
+                               do_IRQ(63 - dclz(mask_h), regs);
+                       else
+                               do_IRQ(127 - dclz(mask_l), regs);
+               }
+       }
+}
diff --git a/arch/mips/sibyte/bcm1480/irq_handler.S b/arch/mips/sibyte/bcm1480/irq_handler.S
deleted file mode 100644 (file)
index 408db88..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*
- * bcm1480_irq_handler() is the routine that is actually called when an
- * interrupt occurs.  It is installed as the exception vector handler in
- * init_IRQ() in arch/mips/sibyte/bcm1480/irq.c
- *
- * In the handle we figure out which interrupts need handling, and use that
- * to call the dispatcher, which will take care of actually calling
- * registered handlers
- *
- * Note that we take care of all raised interrupts in one go at the handler.
- * This is more BSDish than the Indy code, and also, IMHO, more sane.
- */
-#include <linux/config.h>
-
-#include <asm/addrspace.h>
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/sibyte/sb1250_defs.h>
-#include <asm/sibyte/bcm1480_regs.h>
-#include <asm/sibyte/bcm1480_int.h>
-
-/*
- * What a pain. We have to be really careful saving the upper 32 bits of any
- * register across function calls if we don't want them trashed--since were
- * running in -o32, the calling routing never saves the full 64 bits of a
- * register across a function call.  Being the interrupt handler, we're
- * guaranteed that interrupts are disabled during this code so we don't have
- * to worry about random interrupts blasting the high 32 bits.
- */
-
-       .text
-       .set    push
-       .set    noreorder
-       .set    noat
-       .set    mips64
-       #.set   mips4
-       .align  5
-       NESTED(bcm1480_irq_handler, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-
-#ifdef CONFIG_SIBYTE_BCM1480_PROF
-       /* Set compare to count to silence count/compare timer interrupts */
-       mfc0    t1, CP0_COUNT
-       mtc0    t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
-#endif
-       /* Read cause */
-       mfc0    s0, CP0_CAUSE
-
-#ifdef CONFIG_SIBYTE_BCM1480_PROF
-       /* Cpu performance counter interrupt is routed to IP[7] */
-       andi    t1, s0, CAUSEF_IP7
-       beqz    t1, 0f
-        srl    t1, s0, (CAUSEB_BD-2)   /* Shift BD bit to bit 2 */
-       and     t1, t1, 0x4             /* mask to get just BD bit */
-#ifdef CONFIG_MIPS64
-       dmfc0   a0, CP0_EPC
-       daddu   a0, a0, t1              /* a0 = EPC + (BD ? 4 : 0) */
-#else
-       mfc0    a0, CP0_EPC
-       addu    a0, a0, t1              /* a0 = EPC + (BD ? 4 : 0) */
-#endif
-       jal     sbprof_cpu_intr
-        nop
-       j       ret_from_irq
-        nop
-0:
-#endif
-
-       /* Timer interrupt is routed to IP[4] */
-       andi    t1, s0, CAUSEF_IP4
-       beqz    t1, 1f
-        nop
-       jal     bcm1480_timer_interrupt
-        move   a0, sp                  /* Pass the registers along */
-       j       ret_from_irq
-        nop                            /* delay slot  */
-1:
-
-#ifdef CONFIG_SMP
-       /* Mailbox interrupt is routed to IP[3] */
-       andi     t1, s0, CAUSEF_IP3
-       beqz     t1, 2f
-        nop
-       jal      bcm1480_mailbox_interrupt
-        move    a0, sp
-       j        ret_from_irq
-        nop                            /* delay slot  */
-2:
-#endif
-
-#ifdef CONFIG_KGDB
-       /* KGDB (uart 1) interrupt is routed to IP[6] */
-       andi     t1, s0, CAUSEF_IP6
-       beqz     t1, 3f
-        nop                            /* delay slot  */
-       jal      bcm1480_kgdb_interrupt
-        move    a0, sp
-       j        ret_from_irq
-        nop                            /* delay slot  */
-3:
-#endif
-
-       and      t1, s0, CAUSEF_IP2
-       beqz     t1, 9f
-        nop
-
-       /*
-        * Default...we've hit an IP[2] interrupt, which means we've got
-        * to check the 1480 interrupt registers to figure out what to do
-        * Need to detect which CPU we're on, now that smp_affinity is
-        * supported.
-        */
-       PTR_LA   v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE
-#ifdef CONFIG_SMP
-       lw       t1, TI_CPU($28)
-       sll      t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT
-       addu     v0, v0, t1
-#endif
-
-       /* Read IP[2] status (get both high and low halves of status) */
-       ld       s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0)
-       ld       s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0)
-
-       move     s2, zero       /* intr number  */
-       li       s3, 64
-
-       beqz     s0, 9f         /* No interrupts.  Return.  */
-        move    a1, sp
-
-       xori     s4, s0, 1      /* if s0 (_H) == 1, it's a low intr, so...  */
-       movz     s2, s3, s4     /* start the intr number at 64, and  */
-       movz     s0, s1, s4     /* look at the low status value.  */
-
-       dclz     s1, s0         /* Find the next interrupt.  */
-       dsubu    a0, zero, s1
-       daddiu   a0, a0, 63
-       jal      do_IRQ
-        daddu   a0, a0, s2
-
-9:     j        ret_from_irq
-        nop
-
-       .set pop
-       END(bcm1480_irq_handler)
index a8af846..a2fdbd6 100644 (file)
@@ -1,4 +1,4 @@
-obj-y := setup.o irq.o irq_handler.o time.o
+obj-y := setup.o irq.o time.o
 
 obj-$(CONFIG_SMP)                      += smp.o
 obj-$(CONFIG_SIBYTE_TBPROF)            += bcm1250_tbprof.o
index 589537b..0f6e54d 100644 (file)
@@ -163,10 +163,6 @@ static void sb1250_set_affinity(unsigned int irq, cpumask_t mask)
 }
 #endif
 
-
-/* Defined in arch/mips/sibyte/sb1250/irq_handler.S */
-extern void sb1250_irq_handler(void);
-
 /*****************************************************************************/
 
 static unsigned int startup_sb1250_irq(unsigned int irq)
@@ -379,7 +375,6 @@ void __init arch_init_irq(void)
 #endif
        /* Enable necessary IPs, disable the rest */
        change_c0_status(ST0_IM, imask);
-       set_except_vector(0, sb1250_irq_handler);
 
 #ifdef CONFIG_KGDB
        if (kgdb_flag) {
@@ -409,7 +404,7 @@ void __init arch_init_irq(void)
 #define duart_out(reg, val)     csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
 #define duart_in(reg)           csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
 
-void sb1250_kgdb_interrupt(struct pt_regs *regs)
+static void sb1250_kgdb_interrupt(struct pt_regs *regs)
 {
        /*
         * Clear break-change status (allow some time for the remote
@@ -424,3 +419,74 @@ void sb1250_kgdb_interrupt(struct pt_regs *regs)
 }
 
 #endif         /* CONFIG_KGDB */
+
+static inline int dclz(unsigned long long x)
+{
+       int lz;
+
+       __asm__ (
+       "       .set    push                                            \n"
+       "       .set    mips64                                          \n"
+       "       dclz    %0, %1                                          \n"
+       "       .set    pop                                             \n"
+       : "=r" (lz)
+       : "r" (x));
+
+       return lz;
+}
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending;
+
+#ifdef CONFIG_SIBYTE_SB1250_PROF
+       /* Set compare to count to silence count/compare timer interrupts */
+       write_c0_count(read_c0_count());
+#endif
+
+       /*
+        * What a pain. We have to be really careful saving the upper 32 bits
+        * of any * register across function calls if we don't want them
+        * trashed--since were running in -o32, the calling routing never saves
+        * the full 64 bits of a register across a function call.  Being the
+        * interrupt handler, we're guaranteed that interrupts are disabled
+        * during this code so we don't have to worry about random interrupts
+        * blasting the high 32 bits.
+        */
+
+       pending = read_c0_cause();
+
+#ifdef CONFIG_SIBYTE_SB1250_PROF
+       if (pending & CAUSEF_IP7) { /* Cpu performance counter interrupt */
+               sbprof_cpu_intr(exception_epc(regs));
+       }
+#endif
+
+       if (pending & CAUSEF_IP4)
+               sb1250_timer_interrupt(regs);
+
+#ifdef CONFIG_SMP
+       if (pending & CAUSEF_IP3)
+               sb1250_mailbox_interrupt(regs);
+#endif
+
+#ifdef CONFIG_KGDB
+       if (pending & CAUSEF_IP6)                       /* KGDB (uart 1) */
+               sb1250_kgdb_interrupt(regs);
+#endif
+
+       if (pending & CAUSEF_IP2) {
+               unsigned long long mask;
+
+               /*
+                * Default...we've hit an IP[2] interrupt, which means we've
+                * got to check the 1250 interrupt registers to figure out what
+                * to do.  Need to detect which CPU we're on, now that
+                ~ smp_affinity is supported.
+                */
+               mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
+                                             R_IMR_INTERRUPT_STATUS_BASE)));
+               if (mask)
+                       do_IRQ(63 - dclz(mask), regs);
+       }
+}
diff --git a/arch/mips/sibyte/sb1250/irq_handler.S b/arch/mips/sibyte/sb1250/irq_handler.S
deleted file mode 100644 (file)
index 60edc8f..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*
- * sb1250_handle_int() is the routine that is actually called when an interrupt
- * occurs.  It is installed as the exception vector handler in arch_init_irq()
- * in arch/mips/sibyte/sb1250/irq.c
- *
- * In the handle we figure out which interrupts need handling, and use that to
- * call the dispatcher, which will take care of actually calling registered
- * handlers
- *
- * Note that we take care of all raised interrupts in one go at the handler.
- * This is more BSDish than the Indy code, and also, IMHO, more sane.
- */
-#include <linux/config.h>
-
-#include <asm/addrspace.h>
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/sibyte/sb1250_defs.h>
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/sb1250_int.h>
-
-/*
- * What a pain. We have to be really careful saving the upper 32 bits of any
- * register across function calls if we don't want them trashed--since were
- * running in -o32, the calling routing never saves the full 64 bits of a
- * register across a function call.  Being the interrupt handler, we're
- * guaranteed that interrupts are disabled during this code so we don't have
- * to worry about random interrupts blasting the high 32 bits.
- */
-
-       .text
-       .set    push
-       .set    noreorder
-       .set    noat
-       .set    mips64
-       .align  5
-       NESTED(sb1250_irq_handler, PT_SIZE, sp)
-       SAVE_ALL
-       CLI
-
-#ifdef CONFIG_SIBYTE_SB1250_PROF
-       /* Set compare to count to silence count/compare timer interrupts */
-       mfc0    t1, CP0_COUNT
-       mtc0    t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
-#endif
-       /* Read cause */
-       mfc0    s0, CP0_CAUSE
-
-#ifdef CONFIG_SIBYTE_SB1250_PROF
-       /* Cpu performance counter interrupt is routed to IP[7] */
-       andi    t1, s0, CAUSEF_IP7
-       beqz    t1, 0f
-        srl    t1, s0, (CAUSEB_BD-2)  /* Shift BD bit to bit 2 */
-       and     t1, t1, 0x4             /* mask to get just BD bit */
-       mfc0    a0, CP0_EPC
-       jal     sbprof_cpu_intr
-        addu   a0, a0, t1              /* a0 = EPC + (BD ? 4 : 0) */
-       j       ret_from_irq
-        nop
-0:
-#endif
-
-       /* Timer interrupt is routed to IP[4] */
-       andi    t1, s0, CAUSEF_IP4
-       beqz    t1, 1f
-        nop
-       jal     sb1250_timer_interrupt
-        move   a0, sp                  /* Pass the registers along */
-       j       ret_from_irq
-        nop                            # delay slot
-1:
-
-#ifdef CONFIG_SMP
-       /* Mailbox interrupt is routed to IP[3] */
-       andi     t1, s0, CAUSEF_IP3
-       beqz     t1, 2f
-        nop
-       jal      sb1250_mailbox_interrupt
-        move    a0, sp
-       j       ret_from_irq
-        nop                            # delay slot
-2:
-#endif
-
-#ifdef CONFIG_KGDB
-       /* KGDB (uart 1) interrupt is routed to IP[6] */
-       andi    t1, s0, CAUSEF_IP6
-       beqz    t1, 1f
-       nop                            # delay slot
-       jal     sb1250_kgdb_interrupt
-         move  a0, sp
-       j       ret_from_irq
-       nop                            # delay slot
-1:
-#endif
-
-       and      t1, s0, CAUSEF_IP2
-       beqz     t1, 4f
-        nop
-
-       /*
-        * Default...we've hit an IP[2] interrupt, which means we've got to
-        * check the 1250 interrupt registers to figure out what to do
-        * Need to detect which CPU we're on, now that smp_affinity is supported.
-        */
-       PTR_LA  v0, CKSEG1 + A_IMR_CPU0_BASE
-#ifdef CONFIG_SMP
-       lw      t1, TI_CPU($28)
-       sll     t1, IMR_REGISTER_SPACING_SHIFT
-       addu    v0, t1
-#endif
-       ld      s0, R_IMR_INTERRUPT_STATUS_BASE(v0)     /* read IP[2] status */
-
-       beqz    s0, 4f          /* No interrupts.  Return */
-        move   a1, sp
-
-3:     dclz    s1, s0          /* Find the next interrupt */
-       dsubu   a0, zero, s1
-       daddiu  a0, a0, 63
-       jal      do_IRQ
-        nop
-
-4:     j        ret_from_irq
-        nop
-
-       .set pop
-       END(sb1250_irq_handler)
index 1e5676e..9c7eaa5 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for the SNI specific part of the kernel
 #
 
-obj-y          += int-handler.o irq.o pcimt_scache.o reset.o setup.o
+obj-y          += irq.o pcimt_scache.o reset.o setup.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S
deleted file mode 100644 (file)
index 2cdc09f..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SNI RM200 PCI specific interrupt handler code.
- *
- * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/sni.h>
-#include <asm/stackframe.h>
-
-/*
- * The PCI ASIC has the nasty property that it may delay writes if it is busy.
- * As a consequence from writes that have not graduated when we exit from the
- * interrupt handler we might catch a spurious interrupt.  To avoid this we
- * force the PCI ASIC to graduate all writes by executing a read from the
- * PCI bus.
- */
-               .set    noreorder
-               .set    noat
-               .align  5
-               NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-
-               /* Blinken light ...  */
-               lb      t0, led_cache
-               addiu   t0, 1
-               sb      t0, led_cache
-               sb      t0, PCIMT_CSLED                 # write only register
-               .data
-led_cache:     .byte   0
-               .text
-
-               mfc0    t0, CP0_STATUS
-               mfc0    t1, CP0_CAUSE
-               and     t0, t1
-
-                andi   t1, t0, 0x0800                  # hardware interrupt 1
-               bnez    t1, _hwint1
-                andi   t1, t0, 0x4000                  # hardware interrupt 4
-               bnez    t1, _hwint4
-                andi   t1, t0, 0x2000                  # hardware interrupt 3
-               bnez    t1, _hwint3
-                andi   t1, t0, 0x1000                  # hardware interrupt 2
-               bnez    t1, _hwint2
-                andi   t1, t0, 0x8000                  # hardware interrupt 5
-               bnez    t1, _hwint5
-                andi   t1, t0, 0x0400                  # hardware interrupt 0
-               bnez    t1, _hwint0
-                nop
-
-               j       restore_all                     # spurious interrupt
-                nop
-
- ##############################################################################
-
-/* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
-   button interrupts.  */
-_hwint0:       jal     pciasic_hwint0
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-/*
- * hwint 1 deals with EISA and SCSI interrupts
- */
-_hwint1:       jal     pciasic_hwint1
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-
-/*
- * This interrupt was used for the com1 console on the first prototypes;
- * it's unsed otherwise
- */
-_hwint2:       jal     pciasic_hwint2
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-/*
- * hwint 3 are the PCI interrupts A - D
- */
-_hwint3:       jal     pciasic_hwint3
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-/*
- * hwint 4 is used for only the onboard PCnet 32.
- */
-_hwint4:       jal     pciasic_hwint4
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-/* hwint5 is the r4k count / compare interrupt  */
-_hwint5:       jal     pciasic_hwint5
-                move   a0, sp
-               j       ret_from_irq
-                nop
-
-               END(sni_rm200_pci_handle_int)
index 952038a..7365b48 100644 (file)
@@ -19,8 +19,6 @@
 
 DEFINE_SPINLOCK(pciasic_lock);
 
-extern asmlinkage void sni_rm200_pci_handle_int(void);
-
 static void enable_pciasic_irq(unsigned int irq)
 {
        unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
@@ -71,20 +69,20 @@ static struct hw_interrupt_type pciasic_irq_type = {
  * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
  * button interrupts.  Later ...
  */
-void pciasic_hwint0(struct pt_regs *regs)
+static void pciasic_hwint0(struct pt_regs *regs)
 {
        panic("Received int0 but no handler yet ...");
 }
 
 /* This interrupt was used for the com1 console on the first prototypes.  */
-void pciasic_hwint2(struct pt_regs *regs)
+static void pciasic_hwint2(struct pt_regs *regs)
 {
        /* I think this shouldn't happen on production machines.  */
        panic("hwint2 and no handler yet");
 }
 
 /* hwint5 is the r4k count / compare interrupt  */
-void pciasic_hwint5(struct pt_regs *regs)
+static void pciasic_hwint5(struct pt_regs *regs)
 {
        panic("hwint5 and no handler yet");
 }
@@ -105,7 +103,7 @@ static unsigned int ls1bit8(unsigned int x)
  *
  * The EISA_INT bit in CSITPEND is high active, all others are low active.
  */
-void pciasic_hwint1(struct pt_regs *regs)
+static void pciasic_hwint1(struct pt_regs *regs)
 {
        u8 pend = *(volatile char *)PCIMT_CSITPEND;
        unsigned long flags;
@@ -135,7 +133,7 @@ void pciasic_hwint1(struct pt_regs *regs)
 /*
  * hwint 3 should deal with the PCI A - D interrupts,
  */
-void pciasic_hwint3(struct pt_regs *regs)
+static void pciasic_hwint3(struct pt_regs *regs)
 {
        u8 pend = *(volatile char *)PCIMT_CSITPEND;
        int irq;
@@ -150,13 +148,34 @@ void pciasic_hwint3(struct pt_regs *regs)
 /*
  * hwint 4 is used for only the onboard PCnet 32.
  */
-void pciasic_hwint4(struct pt_regs *regs)
+static void pciasic_hwint4(struct pt_regs *regs)
 {
        clear_c0_status(IE_IRQ4);
        do_IRQ(PCIMT_IRQ_ETHERNET, regs);
        set_c0_status(IE_IRQ4);
 }
 
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_status() & read_c0_cause();
+       static unsigned char led_cache;
+
+       *(volatile unsigned char *) PCIMT_CSLED = ++led_cache;
+
+       if (pending & 0x0800)
+               pciasic_hwint1(regs);
+       else if (pending & 0x4000)
+               pciasic_hwint4(regs);
+       else if (pending & 0x2000)
+               pciasic_hwint3(regs);
+       else if (pending & 0x1000)
+               pciasic_hwint2(regs);
+       else if (pending & 0x8000)
+               pciasic_hwint5(regs);
+       else if (pending & 0x0400)
+               pciasic_hwint0(regs);
+}
+
 void __init init_pciasic(void)
 {
        unsigned long flags;
@@ -176,8 +195,6 @@ void __init arch_init_irq(void)
 {
        int i;
 
-       set_except_vector(0, sni_rm200_pci_handle_int);
-
        init_i8259_irqs();                      /* Integrated i8259  */
        init_pciasic();
 
index 8fa126b..9cb9535 100644 (file)
@@ -6,7 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-obj-y  += tx4927_prom.o tx4927_setup.o tx4927_irq.o tx4927_irq_handler.o
+obj-y  += tx4927_prom.o tx4927_setup.o tx4927_irq.o
 
 obj-$(CONFIG_TOSHIBA_FPCIB0)      += smsc_fdc37m81x.o
 obj-$(CONFIG_KGDB)                 += tx4927_dbgio.o
index 5ab2e2b..8ca6801 100644 (file)
@@ -525,8 +525,6 @@ static void tx4927_irq_pic_end(unsigned int irq)
  */
 void __init tx4927_irq_init(void)
 {
-       extern asmlinkage void tx4927_irq_handler(void);
-
        TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n");
 
        TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n");
@@ -535,16 +533,12 @@ void __init tx4927_irq_init(void)
        TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n");
        tx4927_irq_pic_init();
 
-       TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT,
-                          "=Calling set_except_vector(tx4927_irq_handler)\n");
-       set_except_vector(0, tx4927_irq_handler);
-
        TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n");
 
        return;
 }
 
-int tx4927_irq_nested(void)
+static int tx4927_irq_nested(void)
 {
        int sw_irq = 0;
        u32 level2;
@@ -582,3 +576,25 @@ int tx4927_irq_nested(void)
 
        return (sw_irq);
 }
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_status() & read_c0_cause();
+
+       if (pending & STATUSF_IP7)                      /* cpu timer */
+               do_IRQ(TX4927_IRQ_CPU_TIMER, regs);
+       else if (pending & STATUSF_IP2) {               /* tx4927 pic */
+               unsigned int irq = tx4927_irq_nested();
+
+               if (unlikely(irq == 0)) {
+                       spurious_interrupt(regs);
+                       return;
+               }
+               do_IRQ(irq, regs);
+       } else if (pending & STATUSF_IP0)               /* user line 0 */
+               do_IRQ(TX4927_IRQ_USER0, regs);
+       else if (pending & STATUSF_IP1)                 /* user line 1 */
+               do_IRQ(TX4927_IRQ_USER1, regs);
+       else
+               spurious_interrupt(regs);
+}
diff --git a/arch/mips/tx4927/common/tx4927_irq_handler.S b/arch/mips/tx4927/common/tx4927_irq_handler.S
deleted file mode 100644 (file)
index 0b2ea02..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * linux/arch/mips/tx4927/common/tx4927_irq_handler.S
- *
- * Primary interrupt handler for tx4927 based systems
- *
- * Author: MontaVista Software, Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *         source@mvista.com
- *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/tx4927/tx4927.h>
-
-               .align  5
-               NESTED(tx4927_irq_handler, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-
-               mfc0    t0, CP0_CAUSE
-               mfc0    t1, CP0_STATUS
-               and     t0, t1
-
-               andi    t1, t0, STATUSF_IP7     /* cpu timer */
-               bnez    t1, ll_ip7
-
-               /* IP6..IP3 multiplexed -- do not use */
-
-               andi    t1, t0, STATUSF_IP2     /* tx4927 pic */
-               bnez    t1, ll_ip2
-
-               andi    t1, t0, STATUSF_IP0     /* user line 0 */
-               bnez    t1, ll_ip0
-
-               andi    t1, t0, STATUSF_IP1     /* user line 1 */
-               bnez    t1, ll_ip1
-
-               .set    reorder
-
-               /* wrong alarm or masked ... */
-               jal     spurious_interrupt
-               nop
-               j       ret_from_irq
-               END(tx4927_irq_handler)
-
-               .align  5
-
-
-ll_ip7:
-               li      a0, TX4927_IRQ_CPU_TIMER
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_ip2:
-               jal     tx4927_irq_nested
-               nop
-               beqz    v0, goto_spurious_interrupt
-               nop
-               move    a0, v0
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-goto_spurious_interrupt:
-       j spurious_interrupt
-       nop
-
-ll_ip1:
-               li      a0, TX4927_IRQ_USER1
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_ip0:
-               li      a0, TX4927_IRQ_USER0
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
index 74c95c5..2033ae7 100644 (file)
@@ -6,6 +6,6 @@
 # unless it's something special (ie not a .c file).
 #
 
-obj-y  += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o
+obj-y  += prom.o setup.o irq.o rtc_rx5c348.o
 obj-$(CONFIG_KGDB) += dbgio.o
 
index 4f90d7f..8738051 100644 (file)
@@ -392,11 +392,8 @@ tx4938_irq_pic_end(unsigned int irq)
 void __init
 tx4938_irq_init(void)
 {
-       extern asmlinkage void tx4938_irq_handler(void);
-
        tx4938_irq_cp0_init();
        tx4938_irq_pic_init();
-       set_except_vector(0, tx4938_irq_handler);
 
        return;
 }
@@ -422,3 +419,21 @@ tx4938_irq_nested(void)
        wbflush();
        return (sw_irq);
 }
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status();
+
+       if (pending & STATUSF_IP7)
+               do_IRQ(TX4938_IRQ_CPU_TIMER, regs);
+       else if (pending & STATUSF_IP2) {
+               int irq = tx4938_irq_nested();
+               if (irq)
+                       do_IRQ(irq, regs);
+               else
+                       spurious_interrupt(regs);
+       } else if (pending & STATUSF_IP1)
+               do_IRQ(TX4938_IRQ_USER1, regs);
+       else if (pending & STATUSF_IP0)
+               do_IRQ(TX4938_IRQ_USER0, regs);
+}
diff --git a/arch/mips/tx4938/common/irq_handler.S b/arch/mips/tx4938/common/irq_handler.S
deleted file mode 100644 (file)
index 1b2f72b..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * linux/arch/mips/tx4938/common/handler.S
- *
- * Primary interrupt handler for tx4938 based systems
- * Copyright (C) 2000-2001 Toshiba Corporation
- *
- * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
- * terms of the GNU General Public License version 2. This program is
- * licensed "as is" without any warranty of any kind, whether express
- * or implied.
- *
- * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/tx4938/rbtx4938.h>
-
-
-               .align  5
-               NESTED(tx4938_irq_handler, PT_SIZE, sp)
-               SAVE_ALL
-               CLI
-               .set    at
-
-               mfc0    t0, CP0_CAUSE
-               mfc0    t1, CP0_STATUS
-               and     t0, t1
-
-               andi    t1, t0, STATUSF_IP7     /* cpu timer */
-               bnez    t1, ll_ip7
-
-               /* IP6..IP3 multiplexed -- do not use */
-
-               andi    t1, t0, STATUSF_IP2     /* tx4938 pic */
-               bnez    t1, ll_ip2
-
-               andi    t1, t0, STATUSF_IP1     /* user line 1 */
-               bnez    t1, ll_ip1
-
-               andi    t1, t0, STATUSF_IP0     /* user line 0 */
-               bnez    t1, ll_ip0
-
-               .set    reorder
-
-               nop
-               END(tx4938_irq_handler)
-
-               .align  5
-
-
-ll_ip7:
-               li      a0, TX4938_IRQ_CPU_TIMER
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-
-ll_ip2:
-               jal     tx4938_irq_nested
-               nop
-               beqz    v0, goto_spurious_interrupt
-               nop
-               move    a0, v0
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-goto_spurious_interrupt:
-               j       ret_from_irq
-
-ll_ip1:
-               li      a0, TX4938_IRQ_USER1
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
-
-ll_ip0:
-               li      a0, TX4938_IRQ_USER0
-               move    a1, sp
-               jal     do_IRQ
-               j       ret_from_irq
index 9096302..aa37397 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for common code of the NEC VR4100 series.
 #
 
-obj-y                          += bcu.o cmu.o icu.o init.o int-handler.o irq.o pmu.o type.o
+obj-y                          += bcu.o cmu.o icu.o init.o irq.o pmu.o type.o
 obj-$(CONFIG_VRC4173)          += vrc4173.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/vr41xx/common/int-handler.S b/arch/mips/vr41xx/common/int-handler.S
deleted file mode 100644 (file)
index e865234..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * FILE NAME
- *     arch/mips/vr41xx/common/int-handler.S
- *
- * BRIEF MODULE DESCRIPTION
- *     Interrupt dispatcher for the NEC VR4100 series.
- *
- * Author: Yoichi Yuasa
- *         yyuasa@mvista.com or source@mvista.com
- *
- * Copyright 2001 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/*
- * Changes:
- *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
- *  - New creation, NEC VR4100 series are supported.
- *
- *  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
- *  - Coped with INTASSIGN of NEC VR4133.
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-#include <asm/stackframe.h>
-
-               .text
-               .set    noreorder
-
-               .align  5
-               NESTED(vr41xx_handle_interrupt, PT_SIZE, ra)
-               .set    noat
-               SAVE_ALL
-               CLI
-               .set    at
-               .set    noreorder
-
-               /*
-                * Get the pending interrupts
-                */
-               mfc0    t0, CP0_CAUSE
-               mfc0    t1, CP0_STATUS
-               andi    t0, 0xff00
-               and     t0, t0, t1
-
-               andi    t1, t0, CAUSEF_IP7      # MIPS timer interrupt
-               bnez    t1, handle_irq
-               li      a0, 7
-
-               andi    t1, t0, 0x7800          # check for Int1-4
-               beqz    t1, 1f
-
-               andi    t1, t0, CAUSEF_IP3      # check for Int1
-               bnez    t1, handle_int
-               li      a0, 3
-
-               andi    t1, t0, CAUSEF_IP4      # check for Int2
-               bnez    t1, handle_int
-               li      a0, 4
-
-               andi    t1, t0, CAUSEF_IP5      # check for Int3
-               bnez    t1, handle_int
-               li      a0, 5
-
-               andi    t1, t0, CAUSEF_IP6      # check for Int4
-               bnez    t1, handle_int
-               li      a0, 6
-
-1:
-               andi    t1, t0, CAUSEF_IP2      # check for Int0
-               bnez    t1, handle_int
-               li      a0, 2
-
-               andi    t1, t0, CAUSEF_IP0      # check for IP0
-               bnez    t1, handle_irq
-               li      a0, 0
-
-               andi    t1, t0, CAUSEF_IP1      # check for IP1
-               bnez    t1, handle_irq
-               li      a0, 1
-
-               jal     spurious_interrupt
-               nop
-               j       ret_from_irq
-                nop
-
-handle_int:
-               jal     irq_dispatch
-               move    a1, sp
-               j       ret_from_irq
-               nop
-
-handle_irq:
-               jal     do_IRQ
-               move    a1, sp
-               j       ret_from_irq
-               END(vr41xx_handle_interrupt)
index 61aa264..86796bb 100644 (file)
@@ -59,7 +59,7 @@ int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *)
 
 EXPORT_SYMBOL_GPL(cascade_irq);
 
-asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs)
+static void irq_dispatch(unsigned int irq, struct pt_regs *regs)
 {
        irq_cascade_t *cascade;
        irq_desc_t *desc;
@@ -84,11 +84,32 @@ asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs)
                do_IRQ(irq, regs);
 }
 
-extern asmlinkage void vr41xx_handle_interrupt(void);
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+       if (pending & CAUSEF_IP7)
+               do_IRQ(7, regs);
+       else if (pending & 0x7800) {
+               if (pending & CAUSEF_IP3)
+                       irq_dispatch(3, regs);
+               else if (pending & CAUSEF_IP4)
+                       irq_dispatch(4, regs);
+               else if (pending & CAUSEF_IP5)
+                       irq_dispatch(5, regs);
+               else if (pending & CAUSEF_IP6)
+                       irq_dispatch(6, regs);
+       } else if (pending & CAUSEF_IP2)
+               irq_dispatch(2, regs);
+       else if (pending & CAUSEF_IP0)
+               do_IRQ(0, regs);
+       else if (pending & CAUSEF_IP1)
+               do_IRQ(1, regs);
+       else
+               spurious_interrupt(regs);
+}
 
 void __init arch_init_irq(void)
 {
        mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
-
-       set_except_vector(0, vr41xx_handle_interrupt);
 }