Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[MIPS] Rewrite all the assembler interrupt handlers to C.

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>

+1113 -3387
+1 -1
arch/mips/au1000/common/Makefile
··· 6 6 # Makefile for the Alchemy Au1000 CPU, generic files. 7 7 # 8 8 9 - obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \ 9 + obj-y += prom.o irq.o puts.o time.o reset.o \ 10 10 au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ 11 11 sleeper.o cputable.o dma.o dbdma.o gpio.o 12 12
-69
arch/mips/au1000/common/int-handler.S
··· 1 - /* 2 - * Copyright 2001 MontaVista Software Inc. 3 - * Author: ppopov@mvista.com 4 - * 5 - * Interrupt dispatcher for Au1000 boards. 6 - * 7 - * This program is free software; you can redistribute it and/or modify it 8 - * under the terms of the GNU General Public License as published by the 9 - * Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - */ 12 - #include <asm/asm.h> 13 - #include <asm/mipsregs.h> 14 - #include <asm/addrspace.h> 15 - #include <asm/regdef.h> 16 - #include <asm/stackframe.h> 17 - 18 - .text 19 - .set macro 20 - .set noat 21 - .align 5 22 - 23 - NESTED(au1000_IRQ, PT_SIZE, sp) 24 - SAVE_ALL 25 - CLI # Important: mark KERNEL mode ! 26 - 27 - mfc0 t0,CP0_CAUSE # get pending interrupts 28 - mfc0 t1,CP0_STATUS # get enabled interrupts 29 - and t0,t1 # isolate allowed ones 30 - 31 - andi t0,0xff00 # isolate pending bits 32 - beqz t0, 3f # spurious interrupt 33 - 34 - andi a0, t0, CAUSEF_IP7 35 - beq a0, zero, 1f 36 - move a0, sp 37 - jal mips_timer_interrupt 38 - j ret_from_irq 39 - 40 - 1: 41 - andi a0, t0, CAUSEF_IP2 # Interrupt Controller 0, Request 0 42 - beq a0, zero, 2f 43 - move a0,sp 44 - jal intc0_req0_irqdispatch 45 - j ret_from_irq 46 - 2: 47 - andi a0, t0, CAUSEF_IP3 # Interrupt Controller 0, Request 1 48 - beq a0, zero, 3f 49 - move a0,sp 50 - jal intc0_req1_irqdispatch 51 - j ret_from_irq 52 - 3: 53 - andi a0, t0, CAUSEF_IP4 # Interrupt Controller 1, Request 0 54 - beq a0, zero, 4f 55 - move a0,sp 56 - jal intc1_req0_irqdispatch 57 - j ret_from_irq 58 - 4: 59 - andi a0, t0, CAUSEF_IP5 # Interrupt Controller 1, Request 1 60 - beq a0, zero, 5f 61 - move a0, sp 62 - jal intc1_req1_irqdispatch 63 - j ret_from_irq 64 - 65 - 5: 66 - move a0, sp 67 - jal spurious_interrupt 68 - j ret_from_irq 69 - END(au1000_IRQ)
+18 -2
arch/mips/au1000/common/irq.c
··· 66 66 #define EXT_INTC1_REQ1 5 /* IP 5 */ 67 67 #define MIPS_TIMER_IP 7 /* IP 7 */ 68 68 69 - extern asmlinkage void au1000_IRQ(void); 70 69 extern void set_debug_traps(void); 71 70 extern irq_cpustat_t irq_stat [NR_CPUS]; 72 71 ··· 445 446 extern int au1xxx_ic0_nr_irqs; 446 447 447 448 cp0_status = read_c0_status(); 448 - set_except_vector(0, au1000_IRQ); 449 449 450 450 /* Initialize interrupt controllers to a safe state. 451 451 */ ··· 659 661 au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); 660 662 } 661 663 #endif /* CONFIG_PM */ 664 + 665 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 666 + { 667 + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; 668 + 669 + if (pending & CAUSEF_IP7) 670 + mips_timer_interrupt(regs); 671 + else if (pending & CAUSEF_IP2) 672 + intc0_req0_irqdispatch(regs); 673 + else if (pending & CAUSEF_IP3) 674 + intc0_req1_irqdispatch(regs); 675 + else if (pending & CAUSEF_IP4) 676 + intc1_req0_irqdispatch(regs); 677 + else if (pending & CAUSEF_IP5) 678 + intc1_req1_irqdispatch(regs); 679 + else 680 + spurious_interrupt(regs); 681 + }
+1 -1
arch/mips/cobalt/Makefile
··· 2 2 # Makefile for the Cobalt micro systems family specific parts of the kernel 3 3 # 4 4 5 - obj-y := irq.o int-handler.o reset.o setup.o 5 + obj-y := irq.o reset.o setup.o 6 6 7 7 obj-$(CONFIG_EARLY_PRINTK) += console.o 8 8
-25
arch/mips/cobalt/int-handler.S
··· 1 - /* 2 - * This file is subject to the terms and conditions of the GNU General Public 3 - * License. See the file "COPYING" in the main directory of this archive 4 - * for more details. 5 - * 6 - * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle 7 - * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) 8 - */ 9 - #include <asm/asm.h> 10 - #include <asm/mipsregs.h> 11 - #include <asm/mach-cobalt/cobalt.h> 12 - #include <asm/regdef.h> 13 - #include <asm/stackframe.h> 14 - 15 - .text 16 - .align 5 17 - NESTED(cobalt_handle_int, PT_SIZE, sp) 18 - SAVE_ALL 19 - CLI 20 - 21 - PTR_LA ra, ret_from_irq 22 - move a0, sp 23 - j cobalt_irq 24 - 25 - END(cobalt_handle_int)
+1 -5
arch/mips/cobalt/irq.c
··· 20 20 21 21 #include <asm/mach-cobalt/cobalt.h> 22 22 23 - extern void cobalt_handle_int(void); 24 - 25 23 /* 26 24 * We have two types of interrupts that we handle, ones that come in through 27 25 * the CPU interrupt lines, and ones that come in on the via chip. The CPU ··· 77 79 do_IRQ(irq, regs); 78 80 } 79 81 80 - asmlinkage void cobalt_irq(struct pt_regs *regs) 82 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 81 83 { 82 84 unsigned pending; 83 85 ··· 119 121 * handler is set in cobalt_timer_setup() 120 122 */ 121 123 GALILEO_OUTL(0, GT_INTRMASK_OFS); 122 - 123 - set_except_vector(0, cobalt_handle_int); 124 124 125 125 init_i8259_irqs(); /* 0 ... 15 */ 126 126 mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */
+1 -1
arch/mips/ddb5xxx/ddb5074/Makefile
··· 3 3 # under Linux. 4 4 # 5 5 6 - obj-y += setup.o irq.o int-handler.o nile4_pic.o 6 + obj-y += setup.o irq.o nile4_pic.o 7 7 8 8 EXTRA_AFLAGS := $(CFLAGS)
-120
arch/mips/ddb5xxx/ddb5074/int-handler.S
··· 1 - /* 2 - * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler 3 - * 4 - * Based on arch/mips/sgi/kernel/indyIRQ.S 5 - * 6 - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 7 - * 8 - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> 9 - * Sony Software Development Center Europe (SDCE), Brussels 10 - */ 11 - #include <asm/asm.h> 12 - #include <asm/mipsregs.h> 13 - #include <asm/regdef.h> 14 - #include <asm/stackframe.h> 15 - 16 - /* A lot of complication here is taken away because: 17 - * 18 - * 1) We handle one interrupt and return, sitting in a loop and moving across 19 - * all the pending IRQ bits in the cause register is _NOT_ the answer, the 20 - * common case is one pending IRQ so optimize in that direction. 21 - * 22 - * 2) We need not check against bits in the status register IRQ mask, that 23 - * would make this routine slow as hell. 24 - * 25 - * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in 26 - * between like BSD spl() brain-damage. 27 - * 28 - * Furthermore, the IRQs on the INDY look basically (barring software IRQs 29 - * which we don't use at all) like: 30 - * 31 - * MIPS IRQ Source 32 - * -------- ------ 33 - * 0 Software (ignored) 34 - * 1 Software (ignored) 35 - * 2 Local IRQ level zero 36 - * 3 Local IRQ level one 37 - * 4 8254 Timer zero 38 - * 5 8254 Timer one 39 - * 6 Bus Error 40 - * 7 R4k timer (what we use) 41 - * 42 - * We handle the IRQ according to _our_ priority which is: 43 - * 44 - * Highest ---- R4k Timer 45 - * Local IRQ zero 46 - * Local IRQ one 47 - * Bus Error 48 - * 8254 Timer zero 49 - * Lowest ---- 8254 Timer one 50 - * 51 - * then we just return, if multiple IRQs are pending then we will just take 52 - * another exception, big deal. 53 - */ 54 - 55 - .text 56 - .set noreorder 57 - .set noat 58 - .align 5 59 - NESTED(ddbIRQ, PT_SIZE, sp) 60 - SAVE_ALL 61 - CLI 62 - .set at 63 - mfc0 s0, CP0_CAUSE # get irq mask 64 - 65 - #if 1 66 - mfc0 t2,CP0_STATUS # get enabled interrupts 67 - and s0,t2 # isolate allowed ones 68 - #endif 69 - /* First we check for r4k counter/timer IRQ. */ 70 - andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero 71 - beq a0, zero, 1f 72 - andi a0, s0, CAUSEF_IP3 # delay slot, check local level one 73 - 74 - /* Wheee, local level zero interrupt. */ 75 - jal ddb_local0_irqdispatch 76 - move a0, sp # delay slot 77 - 78 - j ret_from_irq 79 - nop # delay slot 80 - 81 - 1: 82 - beq a0, zero, 1f 83 - andi a0, s0, CAUSEF_IP6 # delay slot, check bus error 84 - 85 - /* Wheee, local level one interrupt. */ 86 - move a0, sp 87 - jal ddb_local1_irqdispatch 88 - nop 89 - 90 - j ret_from_irq 91 - nop 92 - 93 - 1: 94 - beq a0, zero, 1f 95 - nop 96 - 97 - /* Wheee, an asynchronous bus error... */ 98 - move a0, sp 99 - jal ddb_buserror_irq 100 - nop 101 - 102 - j ret_from_irq 103 - nop 104 - 105 - 1: 106 - /* Here by mistake? This is possible, what can happen 107 - * is that by the time we take the exception the IRQ 108 - * pin goes low, so just leave if this is the case. 109 - */ 110 - andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) 111 - beq a0, zero, 1f 112 - 113 - /* Must be one of the 8254 timers... */ 114 - move a0, sp 115 - jal ddb_8254timer_irq 116 - nop 117 - 1: 118 - j ret_from_irq 119 - nop 120 - END(ddbIRQ)
+18 -8
arch/mips/ddb5xxx/ddb5074/irq.c
··· 21 21 #include <asm/ddb5xxx/ddb5074.h> 22 22 23 23 24 - extern asmlinkage void ddbIRQ(void); 25 - 26 24 static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; 27 25 28 26 #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ ··· 88 90 89 91 } 90 92 91 - void ddb_local0_irqdispatch(struct pt_regs *regs) 93 + static void ddb_local0_irqdispatch(struct pt_regs *regs) 92 94 { 93 95 u32 mask; 94 96 int nile4_irq; ··· 116 118 } 117 119 } 118 120 119 - void ddb_local1_irqdispatch(void) 121 + static void ddb_local1_irqdispatch(void) 120 122 { 121 123 printk("ddb_local1_irqdispatch called\n"); 122 124 } 123 125 124 - void ddb_buserror_irq(void) 126 + static void ddb_buserror_irq(void) 125 127 { 126 128 printk("ddb_buserror_irq called\n"); 127 129 } 128 130 129 - void ddb_8254timer_irq(void) 131 + static void ddb_8254timer_irq(void) 130 132 { 131 133 printk("ddb_8254timer_irq called\n"); 134 + } 135 + 136 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 137 + { 138 + unsigned int pending = read_c0_cause() & read_c0_status(); 139 + 140 + if (pending & CAUSEF_IP2) 141 + ddb_local0_irqdispatch(regs); 142 + else if (pending & CAUSEF_IP3) 143 + ddb_local1_irqdispatch(); 144 + else if (pending & CAUSEF_IP6) 145 + ddb_buserror_irq(); 146 + else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) 147 + ddb_8254timer_irq(); 132 148 } 133 149 134 150 void __init arch_init_irq(void) ··· 150 138 /* setup cascade interrupts */ 151 139 setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade); 152 140 setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade); 153 - 154 - set_except_vector(0, ddbIRQ); 155 141 156 142 nile4_irq_setup(NILE4_IRQ_BASE); 157 143 m1543_irq_setup();
+1 -1
arch/mips/ddb5xxx/ddb5476/Makefile
··· 3 3 # under Linux. 4 4 # 5 5 6 - obj-y += setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o 6 + obj-y += setup.o irq.o nile4_pic.o vrc5476_irq.o 7 7 obj-$(CONFIG_KGDB) += dbg_io.o 8 8 9 9 EXTRA_AFLAGS := $(CFLAGS)
-113
arch/mips/ddb5xxx/ddb5476/int-handler.S
··· 1 - /* 2 - * Copyright 2001 MontaVista Software Inc. 3 - * Author: jsun@mvista.com or jsun@junsun.net 4 - * 5 - * First-level interrupt dispatcher for ddb5476 6 - * 7 - * This program is free software; you can redistribute it and/or modify it 8 - * under the terms of the GNU General Public License as published by the 9 - * Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - */ 12 - #include <asm/asm.h> 13 - #include <asm/mipsregs.h> 14 - #include <asm/addrspace.h> 15 - #include <asm/regdef.h> 16 - #include <asm/stackframe.h> 17 - 18 - #include <asm/ddb5xxx/ddb5476.h> 19 - 20 - /* 21 - * first level interrupt dispatcher for ocelot board - 22 - * We check for the timer first, then check PCI ints A and D. 23 - * Then check for serial IRQ and fall through. 24 - */ 25 - .align 5 26 - NESTED(ddb5476_handle_int, PT_SIZE, sp) 27 - SAVE_ALL 28 - CLI 29 - .set at 30 - .set noreorder 31 - mfc0 t0, CP0_CAUSE 32 - mfc0 t2, CP0_STATUS 33 - 34 - and t0, t2 35 - 36 - andi t1, t0, STATUSF_IP7 /* cpu timer */ 37 - bnez t1, ll_cpu_ip7 38 - andi t1, t0, STATUSF_IP2 /* vrc5476 & i8259 */ 39 - bnez t1, ll_cpu_ip2 40 - andi t1, t0, STATUSF_IP3 41 - bnez t1, ll_cpu_ip3 42 - andi t1, t0, STATUSF_IP4 43 - bnez t1, ll_cpu_ip4 44 - andi t1, t0, STATUSF_IP5 45 - bnez t1, ll_cpu_ip5 46 - andi t1, t0, STATUSF_IP6 47 - bnez t1, ll_cpu_ip6 48 - andi t1, t0, STATUSF_IP0 /* software int 0 */ 49 - bnez t1, ll_cpu_ip0 50 - andi t1, t0, STATUSF_IP1 /* software int 1 */ 51 - bnez t1, ll_cpu_ip1 52 - nop 53 - 54 - .set reorder 55 - 56 - /* wrong alarm or masked ... */ 57 - // jal spurious_interrupt 58 - // j ret_from_irq 59 - move a0, sp 60 - jal vrc5476_irq_dispatch 61 - j ret_from_irq 62 - nop 63 - 64 - .align 5 65 - 66 - ll_cpu_ip0: 67 - li a0, CPU_IRQ_BASE + 0 68 - move a1, sp 69 - jal do_IRQ 70 - j ret_from_irq 71 - 72 - ll_cpu_ip1: 73 - li a0, CPU_IRQ_BASE + 1 74 - move a1, sp 75 - jal do_IRQ 76 - j ret_from_irq 77 - 78 - ll_cpu_ip2: /* jump to second-level dispatching */ 79 - move a0, sp 80 - jal vrc5476_irq_dispatch 81 - j ret_from_irq 82 - 83 - ll_cpu_ip3: 84 - li a0, CPU_IRQ_BASE + 3 85 - move a1, sp 86 - jal do_IRQ 87 - j ret_from_irq 88 - 89 - ll_cpu_ip4: 90 - li a0, CPU_IRQ_BASE + 4 91 - move a1, sp 92 - jal do_IRQ 93 - j ret_from_irq 94 - 95 - ll_cpu_ip5: 96 - li a0, CPU_IRQ_BASE + 5 97 - move a1, sp 98 - jal do_IRQ 99 - j ret_from_irq 100 - 101 - ll_cpu_ip6: 102 - li a0, CPU_IRQ_BASE + 6 103 - move a1, sp 104 - jal do_IRQ 105 - j ret_from_irq 106 - 107 - ll_cpu_ip7: 108 - li a0, CPU_IRQ_BASE + 7 109 - move a1, sp 110 - jal do_IRQ 111 - j ret_from_irq 112 - 113 - END(ddb5476_handle_int)
+26 -4
arch/mips/ddb5xxx/ddb5476/irq.c
··· 110 110 static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; 111 111 static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; 112 112 113 - extern asmlinkage void ddb5476_handle_int(void); 114 113 extern int setup_irq(unsigned int irq, struct irqaction *irqaction); 115 114 extern void mips_cpu_irq_init(u32 irq_base); 116 115 extern void vrc5476_irq_init(u32 irq_base); 116 + 117 + extern void vrc5476_irq_dispatch(struct pt_regs *regs); 118 + 119 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 120 + { 121 + unsigned int pending = read_c0_cause() & read_c0_status(); 122 + 123 + if (pending & STATUSF_IP7) 124 + do_IRQ(CPU_IRQ_BASE + 7, regs); 125 + else if (pending & STATUSF_IP2) 126 + vrc5476_irq_dispatch(regs); 127 + else if (pending & STATUSF_IP3) 128 + do_IRQ(CPU_IRQ_BASE + 3, regs); 129 + else if (pending & STATUSF_IP4) 130 + do_IRQ(CPU_IRQ_BASE + 4, regs); 131 + else if (pending & STATUSF_IP5) 132 + do_IRQ(CPU_IRQ_BASE + 5, regs); 133 + else if (pending & STATUSF_IP6) 134 + do_IRQ(CPU_IRQ_BASE + 6, regs); 135 + else if (pending & STATUSF_IP0) 136 + do_IRQ(CPU_IRQ_BASE, regs); 137 + else if (pending & STATUSF_IP1) 138 + do_IRQ(CPU_IRQ_BASE + 1, regs); 139 + 140 + vrc5476_irq_dispatch(regs); 141 + } 117 142 118 143 void __init arch_init_irq(void) 119 144 { ··· 162 137 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error); 163 138 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error); 164 139 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error); 165 - 166 - /* setup the grandpa intr vector */ 167 - set_except_vector(0, ddb5476_handle_int); 168 140 }
+1 -1
arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
··· 77 77 } 78 78 79 79 80 - asmlinkage void 80 + void 81 81 vrc5476_irq_dispatch(struct pt_regs *regs) 82 82 { 83 83 u32 mask;
+1 -1
arch/mips/ddb5xxx/ddb5477/Makefile
··· 2 2 # Makefile for NEC DDB-Vrc5477 board 3 3 # 4 4 5 - obj-y += int-handler.o irq.o irq_5477.o setup.o lcd44780.o 5 + obj-y += irq.o irq_5477.o setup.o lcd44780.o 6 6 7 7 obj-$(CONFIG_RUNTIME_DEBUG) += debug.o 8 8 obj-$(CONFIG_KGDB) += kgdb_io.o
-75
arch/mips/ddb5xxx/ddb5477/int-handler.S
··· 1 - /* 2 - * Copyright 2001 MontaVista Software Inc. 3 - * Author: jsun@mvista.com or jsun@junsun.net 4 - * 5 - * First-level interrupt dispatcher for ddb5477 6 - * 7 - * This program is free software; you can redistribute it and/or modify it 8 - * under the terms of the GNU General Public License as published by the 9 - * Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - */ 12 - #include <asm/asm.h> 13 - #include <asm/mipsregs.h> 14 - #include <asm/addrspace.h> 15 - #include <asm/regdef.h> 16 - #include <asm/stackframe.h> 17 - #include <asm/ddb5xxx/ddb5477.h> 18 - 19 - /* 20 - * first level interrupt dispatcher for ocelot board - 21 - * We check for the timer first, then check PCI ints A and D. 22 - * Then check for serial IRQ and fall through. 23 - */ 24 - .align 5 25 - NESTED(ddb5477_handle_int, PT_SIZE, sp) 26 - SAVE_ALL 27 - CLI 28 - .set at 29 - .set noreorder 30 - mfc0 t0, CP0_CAUSE 31 - mfc0 t2, CP0_STATUS 32 - 33 - and t0, t2 34 - 35 - andi t1, t0, STATUSF_IP7 /* cpu timer */ 36 - bnez t1, ll_cputimer_irq 37 - andi t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 ) 38 - bnez t1, ll_vrc5477_irq 39 - andi t1, t0, STATUSF_IP0 /* software int 0 */ 40 - bnez t1, ll_cpu_ip0 41 - andi t1, t0, STATUSF_IP1 /* software int 1 */ 42 - bnez t1, ll_cpu_ip1 43 - nop 44 - .set reorder 45 - 46 - /* wrong alarm or masked ... */ 47 - jal spurious_interrupt 48 - j ret_from_irq 49 - END(ddb5477_handle_int) 50 - 51 - .align 5 52 - 53 - ll_vrc5477_irq: 54 - move a0, sp 55 - jal vrc5477_irq_dispatch 56 - j ret_from_irq 57 - 58 - ll_cputimer_irq: 59 - li a0, CPU_IRQ_BASE + 7 60 - move a1, sp 61 - jal do_IRQ 62 - j ret_from_irq 63 - 64 - 65 - ll_cpu_ip0: 66 - li a0, CPU_IRQ_BASE + 0 67 - move a1, sp 68 - jal do_IRQ 69 - j ret_from_irq 70 - 71 - ll_cpu_ip1: 72 - li a0, CPU_IRQ_BASE + 1 73 - move a1, sp 74 - jal do_IRQ 75 - j ret_from_irq
+19 -5
arch/mips/ddb5xxx/ddb5477/irq.c
··· 75 75 76 76 extern void vrc5477_irq_init(u32 base); 77 77 extern void mips_cpu_irq_init(u32 base); 78 - extern asmlinkage void ddb5477_handle_int(void); 79 78 extern int setup_irq(unsigned int irq, struct irqaction *irqaction); 80 79 static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; 81 80 ··· 134 135 /* setup cascade interrupts */ 135 136 setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); 136 137 setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); 137 - 138 - /* hook up the first-level interrupt handler */ 139 - set_except_vector(0, ddb5477_handle_int); 140 138 } 141 139 142 140 u8 i8259_interrupt_ack(void) ··· 155 159 * the first level int-handler will jump here if it is a vrc5477 irq 156 160 */ 157 161 #define NUM_5477_IRQS 32 158 - asmlinkage void 162 + static void 159 163 vrc5477_irq_dispatch(struct pt_regs *regs) 160 164 { 161 165 u32 intStatus; ··· 192 196 return; 193 197 } 194 198 } 199 + } 200 + 201 + #define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6) 202 + 203 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 204 + { 205 + unsigned int pending = read_c0_cause() & read_c0_status(); 206 + 207 + if (pending & STATUSF_IP7) 208 + do_IRQ(CPU_IRQ_BASE + 7, regs); 209 + else if (pending & VR5477INTS) 210 + vrc5477_irq_dispatch(regs); 211 + else if (pending & STATUSF_IP0) 212 + do_IRQ(CPU_IRQ_BASE, regs); 213 + else if (pending & STATUSF_IP1) 214 + do_IRQ(CPU_IRQ_BASE + 1, regs); 215 + else 216 + spurious_interrupt(regs); 195 217 }
+3 -7
arch/mips/dec/int-handler.S
··· 36 36 .text 37 37 .set noreorder 38 38 /* 39 - * decstation_handle_int: Interrupt handler for DECstations 39 + * plat_irq_dispatch: Interrupt handler for DECstations 40 40 * 41 41 * We follow the model in the Indy interrupt code by David Miller, where he 42 42 * says: a lot of complication here is taken away because: ··· 125 125 * just take another exception, big deal. 126 126 */ 127 127 .align 5 128 - NESTED(decstation_handle_int, PT_SIZE, ra) 129 - .set noat 130 - SAVE_ALL 131 - CLI # TEST: interrupts should be off 132 - .set at 128 + NESTED(plat_irq_dispatch, PT_SIZE, ra) 133 129 .set noreorder 134 130 135 131 /* ··· 282 286 nop 283 287 j ret_from_irq 284 288 nop 285 - END(decstation_handle_int) 289 + END(plat_irq_dispatch) 286 290 287 291 /* 288 292 * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl
-3
arch/mips/dec/setup.c
··· 48 48 extern void dec_machine_power_off(void); 49 49 extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs); 50 50 51 - extern asmlinkage void decstation_handle_int(void); 52 - 53 51 unsigned long dec_kn_slot_base, dec_kn_slot_size; 54 52 55 53 EXPORT_SYMBOL(dec_kn_slot_base); ··· 742 744 panic("Don't know how to set this up!"); 743 745 break; 744 746 } 745 - set_except_vector(0, decstation_handle_int); 746 747 747 748 /* Free the FPU interrupt if the exception is present. */ 748 749 if (!cpu_has_nofpuex) {
+1 -1
arch/mips/galileo-boards/ev96100/Makefile
··· 6 6 # Makefile for the Galileo EV96100 board. 7 7 # 8 8 9 - obj-y += init.o irq.o puts.o reset.o time.o int-handler.o setup.o 9 + obj-y += init.o irq.o puts.o reset.o time.o setup.o
-34
arch/mips/galileo-boards/ev96100/int-handler.S
··· 1 - #include <asm/asm.h> 2 - #include <asm/mipsregs.h> 3 - #include <asm/regdef.h> 4 - #include <asm/stackframe.h> 5 - 6 - .set noat 7 - .align 5 8 - 9 - NESTED(ev96100IRQ, PT_SIZE, sp) 10 - SAVE_ALL 11 - CLI # Important: mark KERNEL mode ! 12 - 13 - mfc0 t0, CP0_CAUSE # get pending interrupts 14 - mfc0 t1, CP0_STATUS # get enabled interrupts 15 - and t0, t1 # isolate allowed ones 16 - 17 - # FIX ME add R7000 extensions 18 - andi t0,0xff00 # isolate pending bits 19 - andi a0, t0, CAUSEF_IP7 20 - beq a0, zero, 1f 21 - move a0, sp 22 - jal mips_timer_interrupt 23 - j ret_from_irq 24 - 25 - 1: beqz t0, 3f # spurious interrupt 26 - 27 - move a0, t0 28 - move a1, sp 29 - jal ev96100_cpu_irq 30 - j ret_from_irq 31 - 32 - 3: jal spurious_interrupt 33 - j ret_from_irq 34 - END(ev96100IRQ)
+14 -3
arch/mips/galileo-boards/ev96100/irq.c
··· 40 40 #include <linux/interrupt.h> 41 41 #include <asm/irq_cpu.h> 42 42 43 - extern asmlinkage void ev96100IRQ(void); 44 - 45 43 static inline unsigned int ffz8(unsigned int word) 46 44 { 47 45 unsigned long k; ··· 52 54 return k; 53 55 } 54 56 57 + extern void mips_timer_interrupt(struct pt_regs *regs); 58 + 55 59 asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs) 56 60 { 57 61 do_IRQ(ffz8(pending >> 8), regs); 58 62 } 59 63 64 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 65 + { 66 + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 67 + 68 + if (pending & CAUSEF_IP7) 69 + mips_timer_interrupt(regs); 70 + else if (pending) 71 + ev96100_cpu_irq(pending, regs); 72 + else 73 + spurious_interrupt(regs); 74 + } 75 + 60 76 void __init arch_init_irq(void) 61 77 { 62 - set_except_vector(0, ev96100IRQ); 63 78 mips_cpu_irq_init(0); 64 79 }
+1 -1
arch/mips/gt64120/ev64120/Makefile
··· 6 6 # Makefile for the Galileo EV64120 board. 7 7 # 8 8 9 - obj-y += int-handler.o irq.o promcon.o reset.o serialGT.o setup.o 9 + obj-y += irq.o promcon.o reset.o serialGT.o setup.o 10 10 11 11 EXTRA_AFLAGS := $(CFLAGS)
-114
arch/mips/gt64120/ev64120/int-handler.S
··· 1 - /* 2 - * int-handler.S 3 - * 4 - * Based on the cobalt handler. 5 - */ 6 - #include <asm/asm.h> 7 - #include <asm/mipsregs.h> 8 - #include <asm/addrspace.h> 9 - #include <asm/regdef.h> 10 - #include <asm/stackframe.h> 11 - 12 - /* 13 - * galileo_handle_int - 14 - * We check for the timer first, then check PCI ints A and D. 15 - * Then check for serial IRQ and fall through. 16 - */ 17 - .align 5 18 - .set reorder 19 - .set noat 20 - NESTED(galileo_handle_int, PT_SIZE, sp) 21 - SAVE_ALL 22 - CLI 23 - .set at 24 - mfc0 t0,CP0_CAUSE 25 - mfc0 t2,CP0_STATUS 26 - 27 - and t0,t2 28 - 29 - andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */ 30 - bnez t1,ll_gt64120_irq 31 - andi t1,t0,STATUSF_IP2 /* int0 hardware line */ 32 - bnez t1,ll_pci_intA 33 - andi t1,t0,STATUSF_IP5 /* int3 hardware line */ 34 - bnez t1,ll_pci_intD 35 - andi t1,t0,STATUSF_IP6 /* int4 hardware line */ 36 - bnez t1,ll_serial_irq 37 - andi t1,t0,STATUSF_IP7 /* compare int */ 38 - bnez t1,ll_compare_irq 39 - nop 40 - 41 - /* wrong alarm or masked ... */ 42 - jal spurious_interrupt 43 - nop 44 - j ret_from_irq 45 - END(galileo_handle_int) 46 - 47 - 48 - .align 5 49 - .set reorder 50 - ll_gt64120_irq: 51 - li a0,4 52 - move a1,sp 53 - jal do_IRQ 54 - nop 55 - j ret_from_irq 56 - nop 57 - 58 - .align 5 59 - .set reorder 60 - ll_compare_irq: 61 - li a0,7 62 - move a1,sp 63 - jal do_IRQ 64 - nop 65 - j ret_from_irq 66 - nop 67 - 68 - .align 5 69 - .set reorder 70 - ll_pci_intA: 71 - move a0,sp 72 - jal pci_intA 73 - nop 74 - j ret_from_irq 75 - nop 76 - 77 - #if 0 78 - .align 5 79 - .set reorder 80 - ll_pci_intB: 81 - move a0,sp 82 - jal pci_intB 83 - nop 84 - j ret_from_irq 85 - nop 86 - 87 - .align 5 88 - .set reorder 89 - ll_pci_intC: 90 - move a0,sp 91 - jal pci_intC 92 - nop 93 - j ret_from_irq 94 - nop 95 - #endif 96 - 97 - .align 5 98 - .set reorder 99 - ll_pci_intD: 100 - move a0,sp 101 - jal pci_intD 102 - nop 103 - j ret_from_irq 104 - nop 105 - 106 - .align 5 107 - .set reorder 108 - ll_serial_irq: 109 - li a0,6 110 - move a1,sp 111 - jal do_IRQ 112 - nop 113 - j ret_from_irq 114 - nop
+14 -11
arch/mips/gt64120/ev64120/irq.c
··· 46 46 #include <asm/system.h> 47 47 #include <asm/gt64120.h> 48 48 49 - asmlinkage inline void pci_intA(struct pt_regs *regs) 49 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 50 50 { 51 - do_IRQ(GT_INTA, regs); 52 - } 51 + unsigned int pending = read_c0_status() & read_c0_cause(); 53 52 54 - asmlinkage inline void pci_intD(struct pt_regs *regs) 55 - { 56 - do_IRQ(GT_INTD, regs); 53 + if (pending & STATUSF_IP4) /* int2 hardware line (timer) */ 54 + do_IRQ(4, regs); 55 + else if (pending & STATUSF_IP2) /* int0 hardware line */ 56 + do_IRQ(GT_INTA, regs); 57 + else if (pending & STATUSF_IP5) /* int3 hardware line */ 58 + do_IRQ(GT_INTD, regs); 59 + else if (pending & STATUSF_IP6) /* int4 hardware line */ 60 + do_IRQ(6, regs); 61 + else if (pending & STATUSF_IP7) /* compare int */ 62 + do_IRQ(7, regs); 63 + else 64 + spurious_interrupt(regs); 57 65 } 58 66 59 67 static void disable_ev64120_irq(unsigned int irq_nr) ··· 117 109 118 110 void gt64120_irq_setup(void) 119 111 { 120 - extern asmlinkage void galileo_handle_int(void); 121 - 122 112 /* 123 113 * Clear all of the interrupts while we change the able around a bit. 124 114 */ 125 115 clear_c0_status(ST0_IM); 126 - 127 - /* Sets the exception_handler array. */ 128 - set_except_vector(0, galileo_handle_int); 129 116 130 117 local_irq_disable(); 131 118
+1 -1
arch/mips/gt64120/momenco_ocelot/Makefile
··· 2 2 # Makefile for Momentum's Ocelot board. 3 3 # 4 4 5 - obj-y += int-handler.o irq.o prom.o reset.o setup.o 5 + obj-y += irq.o prom.o reset.o setup.o 6 6 7 7 obj-$(CONFIG_KGDB) += dbg_io.o 8 8
-131
arch/mips/gt64120/momenco_ocelot/int-handler.S
··· 1 - /* 2 - * Copyright 2001 MontaVista Software Inc. 3 - * Author: jsun@mvista.com or jsun@junsun.net 4 - * 5 - * First-level interrupt dispatcher for ocelot board. 6 - * 7 - * This program is free software; you can redistribute it and/or modify it 8 - * under the terms of the GNU General Public License as published by the 9 - * Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - */ 12 - #include <asm/asm.h> 13 - #include <asm/mipsregs.h> 14 - #include <asm/addrspace.h> 15 - #include <asm/regdef.h> 16 - #include <asm/stackframe.h> 17 - 18 - /* 19 - * first level interrupt dispatcher for ocelot board - 20 - * We check for the timer first, then check PCI ints A and D. 21 - * Then check for serial IRQ and fall through. 22 - */ 23 - .align 5 24 - NESTED(ocelot_handle_int, PT_SIZE, sp) 25 - SAVE_ALL 26 - CLI 27 - .set at 28 - mfc0 t0, CP0_CAUSE 29 - mfc0 t2, CP0_STATUS 30 - 31 - and t0, t2 32 - 33 - andi t1, t0, STATUSF_IP2 /* int0 hardware line */ 34 - bnez t1, ll_pri_enet_irq 35 - andi t1, t0, STATUSF_IP3 /* int1 hardware line */ 36 - bnez t1, ll_sec_enet_irq 37 - andi t1, t0, STATUSF_IP4 /* int2 hardware line */ 38 - bnez t1, ll_uart1_irq 39 - andi t1, t0, STATUSF_IP5 /* int3 hardware line */ 40 - bnez t1, ll_cpci_irq 41 - andi t1, t0, STATUSF_IP6 /* int4 hardware line */ 42 - bnez t1, ll_galileo_irq 43 - andi t1, t0, STATUSF_IP7 /* cpu timer */ 44 - bnez t1, ll_cputimer_irq 45 - 46 - /* now look at the extended interrupts */ 47 - mfc0 t0, CP0_CAUSE 48 - cfc0 t1, CP0_S1_INTCONTROL 49 - 50 - /* shift the mask 8 bits left to line up the bits */ 51 - sll t2, t1, 8 52 - 53 - and t0, t2 54 - srl t0, t0, 16 55 - 56 - andi t1, t0, STATUSF_IP8 /* int6 hardware line */ 57 - bnez t1, ll_pmc1_irq 58 - andi t1, t0, STATUSF_IP9 /* int7 hardware line */ 59 - bnez t1, ll_pmc2_irq 60 - andi t1, t0, STATUSF_IP10 /* int8 hardware line */ 61 - bnez t1, ll_cpci_abcd_irq 62 - andi t1, t0, STATUSF_IP11 /* int9 hardware line */ 63 - bnez t1, ll_uart2_irq 64 - 65 - .set reorder 66 - 67 - /* wrong alarm or masked ... */ 68 - j spurious_interrupt 69 - nop 70 - END(ocelot_handle_int) 71 - 72 - .align 5 73 - ll_pri_enet_irq: 74 - li a0, 2 75 - move a1, sp 76 - jal do_IRQ 77 - j ret_from_irq 78 - 79 - ll_sec_enet_irq: 80 - li a0, 3 81 - move a1, sp 82 - jal do_IRQ 83 - j ret_from_irq 84 - 85 - ll_uart1_irq: 86 - li a0, 4 87 - move a1, sp 88 - jal do_IRQ 89 - j ret_from_irq 90 - 91 - ll_cpci_irq: 92 - li a0, 5 93 - move a1, sp 94 - jal do_IRQ 95 - j ret_from_irq 96 - 97 - ll_galileo_irq: 98 - li a0, 6 99 - move a1, sp 100 - jal do_IRQ 101 - j ret_from_irq 102 - 103 - ll_cputimer_irq: 104 - li a0, 7 105 - move a1, sp 106 - jal do_IRQ 107 - j ret_from_irq 108 - 109 - ll_pmc1_irq: 110 - li a0, 8 111 - move a1, sp 112 - jal do_IRQ 113 - j ret_from_irq 114 - 115 - ll_pmc2_irq: 116 - li a0, 9 117 - move a1, sp 118 - jal do_IRQ 119 - j ret_from_irq 120 - 121 - ll_cpci_abcd_irq: 122 - li a0, 10 123 - move a1, sp 124 - jal do_IRQ 125 - j ret_from_irq 126 - 127 - ll_uart2_irq: 128 - li a0, 11 129 - move a1, sp 130 - jal do_IRQ 131 - j ret_from_irq
+32 -4
arch/mips/gt64120/momenco_ocelot/irq.c
··· 48 48 #include <asm/mipsregs.h> 49 49 #include <asm/system.h> 50 50 51 - extern asmlinkage void ocelot_handle_int(void); 51 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 52 + { 53 + unsigned int pending = read_c0_status() & read_c0_cause(); 54 + 55 + if (pending & STATUSF_IP2) /* int0 hardware line */ 56 + do_IRQ(2, regs); 57 + else if (pending & STATUSF_IP3) /* int1 hardware line */ 58 + do_IRQ(3, regs); 59 + else if (pending & STATUSF_IP4) /* int2 hardware line */ 60 + do_IRQ(4, regs); 61 + else if (pending & STATUSF_IP5) /* int3 hardware line */ 62 + do_IRQ(5, regs); 63 + else if (pending & STATUSF_IP6) /* int4 hardware line */ 64 + do_IRQ(6, regs); 65 + else if (pending & STATUSF_IP7) /* cpu timer */ 66 + do_IRQ(7, regs); 67 + else { 68 + /* 69 + * Now look at the extended interrupts 70 + */ 71 + pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; 72 + 73 + if (pending & STATUSF_IP8) /* int6 hardware line */ 74 + do_IRQ(8, regs); 75 + else if (pending & STATUSF_IP9) /* int7 hardware line */ 76 + do_IRQ(9, regs); 77 + else if (pending & STATUSF_IP10) /* int8 hardware line */ 78 + do_IRQ(10, regs); 79 + else if (pending & STATUSF_IP11) /* int9 hardware line */ 80 + do_IRQ(11, regs); 81 + } 82 + } 52 83 53 84 void __init arch_init_irq(void) 54 85 { ··· 89 58 */ 90 59 clear_c0_status(ST0_IM); 91 60 local_irq_disable(); 92 - 93 - /* Sets the first-level interrupt dispatcher. */ 94 - set_except_vector(0, ocelot_handle_int); 95 61 96 62 mips_cpu_irq_init(0); 97 63 rm7k_cpu_irq_init(8);
+1 -1
arch/mips/ite-boards/generic/Makefile
··· 6 6 # Makefile for the ITE 8172 (qed-4n-s01b) board, generic files. 7 7 # 8 8 9 - obj-y += it8172_setup.o irq.o int-handler.o pmon_prom.o \ 9 + obj-y += it8172_setup.o irq.o pmon_prom.o \ 10 10 time.o lpc.o puts.o reset.o 11 11 12 12 obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o
-63
arch/mips/ite-boards/generic/int-handler.S
··· 1 - #include <asm/asm.h> 2 - #include <asm/mipsregs.h> 3 - #include <asm/regdef.h> 4 - #include <asm/stackframe.h> 5 - 6 - .text 7 - .set macro 8 - .set noat 9 - .align 5 10 - 11 - NESTED(it8172_IRQ, PT_SIZE, sp) 12 - SAVE_ALL 13 - CLI # Important: mark KERNEL mode ! 14 - 15 - /* We're working with 'reorder' set at this point. */ 16 - /* 17 - * Get pending interrupts 18 - */ 19 - 20 - mfc0 t0,CP0_CAUSE # get pending interrupts 21 - mfc0 t1,CP0_STATUS # get enabled interrupts 22 - and t0,t1 # isolate allowed ones 23 - 24 - andi t0,0xff00 # isolate pending bits 25 - beqz t0, 3f # spurious interrupt 26 - 27 - andi a0, t0, CAUSEF_IP7 28 - beq a0, zero, 1f 29 - 30 - li a0, 127 # MIPS_CPU_TIMER_IRQ = (NR_IRQS-1) 31 - move a1, sp 32 - jal ll_timer_interrupt 33 - j ret_from_irq 34 - nop 35 - 36 - 1: 37 - andi a0, t0, CAUSEF_IP2 # the only int we expect at this time 38 - beq a0, zero, 3f 39 - move a0,sp 40 - jal it8172_hw0_irqdispatch 41 - 42 - mfc0 t0,CP0_STATUS # disable interrupts 43 - ori t0,1 44 - xori t0,1 45 - mtc0 t0,CP0_STATUS 46 - nop 47 - nop 48 - nop 49 - 50 - la a1, ret_from_irq 51 - jr a1 52 - nop 53 - 54 - 3: 55 - move a0, sp 56 - jal mips_spurious_interrupt 57 - nop 58 - la a1, ret_from_irq 59 - jr a1 60 - nop 61 - 62 - END(it8172_IRQ) 63 -
+12 -3
arch/mips/ite-boards/generic/irq.c
··· 64 64 65 65 extern void set_debug_traps(void); 66 66 extern void mips_timer_interrupt(int irq, struct pt_regs *regs); 67 - extern asmlinkage void it8172_IRQ(void); 68 67 69 68 struct it8172_intc_regs volatile *it8172_hw0_icregs = 70 69 (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE)); ··· 177 178 int i; 178 179 unsigned long flags; 179 180 180 - set_except_vector(0, it8172_IRQ); 181 - 182 181 /* mask all interrupts */ 183 182 it8172_hw0_icregs->lb_mask = 0xffff; 184 183 it8172_hw0_icregs->lpc_mask = 0xffff; ··· 274 277 return; 275 278 276 279 do_IRQ(irq, regs); 280 + } 281 + 282 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 283 + { 284 + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 285 + 286 + if (!pending) 287 + mips_spurious_interrupt(regs); 288 + else if (pending & CAUSEF_IP7) 289 + ll_timer_interrupt(127, regs); 290 + else if (pending & CAUSEF_IP2) 291 + it8172_hw0_irqdispatch(regs); 277 292 } 278 293 279 294 void show_pending_irqs(void)
+1 -1
arch/mips/jazz/Makefile
··· 2 2 # Makefile for the Jazz family specific parts of the kernel 3 3 # 4 4 5 - obj-y := int-handler.o irq.o jazzdma.o reset.o setup.o 5 + obj-y := irq.o jazzdma.o reset.o setup.o 6 6 7 7 EXTRA_AFLAGS := $(CFLAGS)
-283
arch/mips/jazz/int-handler.S
··· 1 - /* 2 - * This file is subject to the terms and conditions of the GNU General Public 3 - * License. See the file "COPYING" in the main directory of this archive 4 - * for more details. 5 - * 6 - * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle and Andreas Busse 7 - * 8 - * Jazz family specific interrupt stuff 9 - * 10 - * To do: On Jazz machines we remap some non-ISA interrupts to ISA 11 - * interrupts. These interrupts should use their own vectors. 12 - * Squeeze the last cycles out of the handlers. Only a dead 13 - * cycle is a good cycle. 14 - */ 15 - #include <asm/asm.h> 16 - #include <asm/mipsregs.h> 17 - #include <asm/jazz.h> 18 - #include <asm/regdef.h> 19 - #include <asm/stackframe.h> 20 - 21 - /* 22 - * jazz_handle_int: Interrupt handler for the ACER Pica-61 boards 23 - */ 24 - .set noreorder 25 - 26 - NESTED(jazz_handle_int, PT_SIZE, ra) 27 - .set noat 28 - SAVE_ALL 29 - CLI 30 - .set at 31 - 32 - /* 33 - * Get pending interrupts 34 - */ 35 - mfc0 t0,CP0_CAUSE # get pending interrupts 36 - mfc0 t1,CP0_STATUS # get enabled interrupts 37 - and t0,t1 # isolate allowed ones 38 - andi t0,0xff00 # isolate pending bits 39 - beqz t0,3f 40 - sll t0,16 # delay slot 41 - 42 - /* 43 - * Find irq with highest priority 44 - * FIXME: This is slow - use binary search 45 - */ 46 - la t1,ll_vectors 47 - 1: bltz t0,2f # found pending irq 48 - sll t0,1 49 - b 1b 50 - subu t1,PTRSIZE # delay slot 51 - 52 - /* 53 - * Do the low-level stuff 54 - */ 55 - 2: lw t0,(t1) 56 - jr t0 57 - nop # delay slot 58 - END(jazz_handle_int) 59 - 60 - ll_sw0: li s1,~IE_SW0 61 - mfc0 t0,CP0_CAUSE 62 - and t0,s1 63 - mtc0 t0,CP0_CAUSE 64 - PANIC("Unimplemented sw0 handler") 65 - 66 - ll_sw1: li s1,~IE_SW1 67 - mfc0 t0,CP0_CAUSE 68 - and t0,s1 69 - mtc0 t0,CP0_CAUSE 70 - PANIC("Unimplemented sw1 handler") 71 - 72 - ll_local_dma: li s1,~IE_IRQ0 73 - PANIC("Unimplemented local_dma handler") 74 - 75 - ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE 76 - #if PTRSIZE == 8 /* True 64 bit kernel */ 77 - dsll t0,1 78 - #endif 79 - .set reorder 80 - LONG_L t0,local_vector(t0) 81 - jr t0 82 - .set noreorder 83 - 84 - /* 85 - * The braindead PICA hardware gives us no way to distinguish if we really 86 - * received interrupt 7 from the (E)ISA bus or if we just received an 87 - * interrupt with no findable cause. This sometimes happens with braindead 88 - * cards. Oh well - for all the Jazz boxes slots are more or less just 89 - * whistles and bells and we're aware of the problem. 90 - */ 91 - ll_isa_irq: lw a0, JAZZ_EISA_IRQ_ACK 92 - 93 - jal do_IRQ 94 - move a1,sp 95 - 96 - j ret_from_irq 97 - nop 98 - 99 - /* 100 - * Hmm... This is not just a plain PC clone so the question is 101 - * which devices on Jazz machines can generate an (E)ISA NMI? 102 - * (Writing to nonexistent memory?) 103 - */ 104 - ll_isa_nmi: li s1,~IE_IRQ3 105 - PANIC("Unimplemented isa_nmi handler") 106 - 107 - /* 108 - * Timer IRQ - remapped to be more similar to an IBM compatible. 109 - * 110 - * The timer interrupt is handled specially to ensure that the jiffies 111 - * variable is updated at all times. Specifically, the timer interrupt is 112 - * just like the complete handlers except that it is invoked with interrupts 113 - * disabled and should never re-enable them. If other interrupts were 114 - * allowed to be processed while the timer interrupt is active, then the 115 - * other interrupts would have to avoid using the jiffies variable for delay 116 - * and interval timing operations to avoid hanging the system. 117 - */ 118 - ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read 119 - li s1,~IE_IRQ4 120 - 121 - li a0, JAZZ_TIMER_IRQ 122 - jal do_IRQ 123 - move a1,sp 124 - 125 - mfc0 t0,CP0_STATUS # disable interrupts again 126 - ori t0,1 127 - xori t0,1 128 - mtc0 t0,CP0_STATUS 129 - 130 - j ret_from_irq 131 - nop 132 - 133 - /* 134 - * CPU count/compare IRQ (unused) 135 - */ 136 - ll_count: j ret_from_irq 137 - mtc0 zero,CP0_COMPARE 138 - 139 - #if 0 140 - /* 141 - * Call the handler for the interrupt 142 - * (Currently unused) 143 - */ 144 - call_real: /* 145 - * temporarily disable interrupt 146 - */ 147 - mfc0 t2,CP0_STATUS 148 - and t2,s1 149 - mtc0 t2,CP0_STATUS 150 - nor s1,zero,s1 151 - jal do_IRQ 152 - 153 - /* 154 - * reenable interrupt 155 - */ 156 - mfc0 t2,CP0_STATUS 157 - or t2,s1 158 - mtc0 t2,CP0_STATUS 159 - j ret_from_irq 160 - #endif 161 - 162 - .data 163 - PTR ll_sw0 # SW0 164 - PTR ll_sw1 # SW1 165 - PTR ll_local_dma # Local DMA 166 - PTR ll_local_dev # Local devices 167 - PTR ll_isa_irq # ISA IRQ 168 - PTR ll_isa_nmi # ISA NMI 169 - PTR ll_timer # Timer 170 - ll_vectors: PTR ll_count # Count/Compare IRQ 171 - 172 - /* 173 - * Interrupt handlers for local devices. 174 - */ 175 - .text 176 - .set reorder 177 - loc_no_irq: PANIC("Unimplemented loc_no_irq handler") 178 - /* 179 - * Parallel port IRQ 180 - */ 181 - loc_parallel: li s1,~JAZZ_IE_PARALLEL 182 - li a0,JAZZ_PARALLEL_IRQ 183 - b loc_call 184 - 185 - /* 186 - * Floppy IRQ 187 - */ 188 - loc_floppy: li s1,~JAZZ_IE_FLOPPY 189 - li a0,JAZZ_FLOPPY_IRQ 190 - b loc_call 191 - 192 - /* 193 - * Sound IRQ 194 - */ 195 - loc_sound: PANIC("Unimplemented loc_sound handler") 196 - loc_video: PANIC("Unimplemented loc_video handler") 197 - 198 - /* 199 - * Ethernet interrupt handler 200 - */ 201 - loc_ethernet: li s1,~JAZZ_IE_ETHERNET 202 - li a0,JAZZ_ETHERNET_IRQ 203 - b loc_call 204 - 205 - /* 206 - * SCSI interrupt handler 207 - */ 208 - loc_scsi: li s1,~JAZZ_IE_SCSI 209 - li a0,JAZZ_SCSI_IRQ 210 - b loc_call 211 - 212 - /* 213 - * Keyboard interrupt handler 214 - */ 215 - loc_keyboard: li s1,~JAZZ_IE_KEYBOARD 216 - li a0,JAZZ_KEYBOARD_IRQ 217 - b loc_call 218 - 219 - /* 220 - * Mouse interrupt handler 221 - */ 222 - loc_mouse: li s1,~JAZZ_IE_MOUSE 223 - li a0,JAZZ_MOUSE_IRQ 224 - b loc_call 225 - 226 - /* 227 - * Serial port 1 IRQ 228 - */ 229 - loc_serial1: li s1,~JAZZ_IE_SERIAL1 230 - li a0,JAZZ_SERIAL1_IRQ 231 - b loc_call 232 - 233 - /* 234 - * Serial port 2 IRQ 235 - */ 236 - loc_serial2: li s1,~JAZZ_IE_SERIAL2 237 - li a0,JAZZ_SERIAL2_IRQ 238 - b loc_call 239 - 240 - /* 241 - * Call the interrupt handler for an interrupt generated by a 242 - * local device. 243 - */ 244 - loc_call: /* 245 - * Temporarily disable interrupt source 246 - */ 247 - lhu t2,JAZZ_IO_IRQ_ENABLE 248 - and t2,s1 249 - sh t2,JAZZ_IO_IRQ_ENABLE 250 - 251 - nor s1,zero,s1 252 - jal do_IRQ 253 - 254 - /* 255 - * Reenable interrupt 256 - */ 257 - lhu t2,JAZZ_IO_IRQ_ENABLE 258 - or t2,s1 259 - sh t2,JAZZ_IO_IRQ_ENABLE 260 - 261 - j ret_from_irq 262 - 263 - /* 264 - * "Jump extender" to reach spurious_interrupt 265 - */ 266 - 3: jal spurious_interrupt 267 - j ret_from_irq 268 - 269 - /* 270 - * Vectors for interrupts generated by local devices 271 - */ 272 - .data 273 - local_vector: PTR loc_no_irq 274 - PTR loc_parallel 275 - PTR loc_floppy 276 - PTR loc_sound 277 - PTR loc_video 278 - PTR loc_ethernet 279 - PTR loc_scsi 280 - PTR loc_keyboard 281 - PTR loc_mouse 282 - PTR loc_serial1 283 - PTR loc_serial2
+74 -4
arch/mips/jazz/irq.c
··· 15 15 #include <asm/io.h> 16 16 #include <asm/jazz.h> 17 17 18 - extern asmlinkage void jazz_handle_int(void); 19 - 20 18 static DEFINE_SPINLOCK(r4030_lock); 21 19 22 20 static void enable_r4030_irq(unsigned int irq) ··· 88 90 */ 89 91 void __init arch_init_irq(void) 90 92 { 91 - set_except_vector(0, jazz_handle_int); 92 - 93 93 init_i8259_irqs(); /* Integrated i8259 */ 94 94 init_r4030_ints(); 95 95 96 96 change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); 97 + } 98 + 99 + static void loc_call(unsigned int irq, struct pt_regs *regs, unsigned int mask) 100 + { 101 + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 102 + r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask); 103 + do_IRQ(irq, regs); 104 + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 105 + r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask); 106 + } 107 + 108 + static void ll_local_dev(struct pt_regs *regs) 109 + { 110 + switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) { 111 + case 0: 112 + panic("Unimplemented loc_no_irq handler"); 113 + break; 114 + case 4: 115 + loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_PARALLEL); 116 + break; 117 + case 8: 118 + loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_FLOPPY); 119 + break; 120 + case 12: 121 + panic("Unimplemented loc_sound handler"); 122 + break; 123 + case 16: 124 + panic("Unimplemented loc_video handler"); 125 + break; 126 + case 20: 127 + loc_call(JAZZ_ETHERNET_IRQ, regs, JAZZ_IE_ETHERNET); 128 + break; 129 + case 24: 130 + loc_call(JAZZ_SCSI_IRQ, regs, JAZZ_IE_SCSI); 131 + break; 132 + case 28: 133 + loc_call(JAZZ_KEYBOARD_IRQ, regs, JAZZ_IE_KEYBOARD); 134 + break; 135 + case 32: 136 + loc_call(JAZZ_MOUSE_IRQ, regs, JAZZ_IE_MOUSE); 137 + break; 138 + case 36: 139 + loc_call(JAZZ_SERIAL1_IRQ, regs, JAZZ_IE_SERIAL1); 140 + break; 141 + case 40: 142 + loc_call(JAZZ_SERIAL2_IRQ, regs, JAZZ_IE_SERIAL2); 143 + break; 144 + } 145 + } 146 + 147 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 148 + { 149 + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 150 + 151 + if (pending & IE_IRQ5) 152 + write_c0_compare(0); 153 + else if (pending & IE_IRQ4) { 154 + r4030_read_reg32(JAZZ_TIMER_REGISTER); 155 + do_IRQ(JAZZ_TIMER_IRQ, regs); 156 + } else if (pending & IE_IRQ3) 157 + panic("Unimplemented ISA NMI handler"); 158 + else if (pending & IE_IRQ2) 159 + do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK), regs); 160 + else if (pending & IE_IRQ1) { 161 + ll_local_dev(regs); 162 + } else if (unlikely(pending & IE_IRQ0)) 163 + panic("Unimplemented local_dma handler"); 164 + else if (pending & IE_SW1) { 165 + clear_c0_cause(IE_SW1); 166 + panic("Unimplemented sw1 handler"); 167 + } else if (pending & IE_SW0) { 168 + clear_c0_cause(IE_SW0); 169 + panic("Unimplemented sw0 handler"); 170 + } 97 171 }
+1 -1
arch/mips/jmr3927/rbhma3100/Makefile
··· 2 2 # Makefile for TOSHIBA JMR-TX3927 board 3 3 # 4 4 5 - obj-y += init.o int-handler.o irq.o setup.o 5 + obj-y += init.o irq.o setup.o 6 6 obj-$(CONFIG_RUNTIME_DEBUG) += debug.o 7 7 obj-$(CONFIG_KGDB) += kgdb_io.o 8 8
-74
arch/mips/jmr3927/rbhma3100/int-handler.S
··· 1 - /* 2 - * Copyright 2001 MontaVista Software Inc. 3 - * Author: MontaVista Software, Inc. 4 - * ahennessy@mvista.com 5 - * 6 - * Based on arch/mips/tsdb/kernel/int-handler.S 7 - * 8 - * Copyright (C) 2000-2001 Toshiba Corporation 9 - * 10 - * This program is free software; you can redistribute it and/or modify it 11 - * under the terms of the GNU General Public License as published by the 12 - * Free Software Foundation; either version 2 of the License, or (at your 13 - * option) any later version. 14 - * 15 - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 18 - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 21 - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 - * 26 - * You should have received a copy of the GNU General Public License along 27 - * with this program; if not, write to the Free Software Foundation, Inc., 28 - * 675 Mass Ave, Cambridge, MA 02139, USA. 29 - */ 30 - 31 - #include <asm/asm.h> 32 - #include <asm/mipsregs.h> 33 - #include <asm/regdef.h> 34 - #include <asm/stackframe.h> 35 - #include <asm/jmr3927/jmr3927.h> 36 - 37 - /* A lot of complication here is taken away because: 38 - * 39 - * 1) We handle one interrupt and return, sitting in a loop 40 - * and moving across all the pending IRQ bits in the cause 41 - * register is _NOT_ the answer, the common case is one 42 - * pending IRQ so optimize in that direction. 43 - * 44 - * 2) We need not check against bits in the status register 45 - * IRQ mask, that would make this routine slow as hell. 46 - * 47 - * 3) Linux only thinks in terms of all IRQs on or all IRQs 48 - * off, nothing in between like BSD spl() brain-damage. 49 - * 50 - */ 51 - 52 - /* Flush write buffer (needed?) 53 - * NOTE: TX39xx performs "non-blocking load", so explicitly use the target 54 - * register of LBU to flush immediately. 55 - */ 56 - #define FLUSH_WB(tmp) \ 57 - la tmp, JMR3927_IOC_REV_ADDR; \ 58 - lbu tmp, (tmp); \ 59 - move tmp, zero; 60 - 61 - .text 62 - .set noreorder 63 - .set noat 64 - .align 5 65 - NESTED(jmr3927_IRQ, PT_SIZE, sp) 66 - SAVE_ALL 67 - CLI 68 - .set at 69 - jal jmr3927_irc_irqdispatch 70 - move a0, sp 71 - FLUSH_WB(t0) 72 - j ret_from_irq 73 - nop 74 - END(jmr3927_IRQ)
+1 -5
arch/mips/jmr3927/rbhma3100/irq.c
··· 77 77 } 78 78 #endif 79 79 80 - extern asmlinkage void jmr3927_IRQ(void); 81 - 82 80 #define irc_dlevel 0 83 81 #define irc_elevel 1 84 82 ··· 260 262 regs->cp0_cause, regs->cp0_epc, regs->regs[31]); 261 263 } 262 264 263 - void jmr3927_irc_irqdispatch(struct pt_regs *regs) 265 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 264 266 { 265 267 int irq; 266 268 ··· 395 397 tx3927_ircptr->imr = irc_elevel; 396 398 397 399 jmr3927_irq_init(NR_ISA_IRQS); 398 - 399 - set_except_vector(0, jmr3927_IRQ); 400 400 401 401 /* setup irq space */ 402 402 add_tb_irq_space(&jmr3927_isac_irqspace);
+14
arch/mips/kernel/genex.S
··· 122 122 .set pop 123 123 END(except_vec3_r4000) 124 124 125 + __FINIT 126 + 127 + .align 5 128 + NESTED(handle_int, PT_SIZE, sp) 129 + SAVE_ALL 130 + CLI 131 + 132 + PTR_LA ra, ret_from_irq 133 + move a0, sp 134 + j plat_irq_dispatch 135 + END(handle_int) 136 + 137 + __INIT 138 + 125 139 /* 126 140 * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. 127 141 * This is a dedicated interrupt exception vector which reduces the
+2
arch/mips/kernel/traps.c
··· 42 42 #include <asm/watch.h> 43 43 #include <asm/types.h> 44 44 45 + extern asmlinkage void handle_int(void); 45 46 extern asmlinkage void handle_tlbm(void); 46 47 extern asmlinkage void handle_tlbl(void); 47 48 extern asmlinkage void handle_tlbs(void); ··· 1297 1296 if (board_be_init) 1298 1297 board_be_init(); 1299 1298 1299 + set_except_vector(0, handle_int); 1300 1300 set_except_vector(1, handle_tlbm); 1301 1301 set_except_vector(2, handle_tlbl); 1302 1302 set_except_vector(3, handle_tlbs);
+1 -1
arch/mips/lasat/Makefile
··· 3 3 # 4 4 5 5 obj-y += reset.o setup.o prom.o lasat_board.o \ 6 - at93c.o interrupt.o lasatIRQ.o 6 + at93c.o interrupt.o 7 7 8 8 obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o 9 9 obj-$(CONFIG_DS1603) += ds1603.o
+8 -6
arch/mips/lasat/interrupt.c
··· 27 27 #include <asm/bootinfo.h> 28 28 #include <asm/irq.h> 29 29 #include <asm/lasat/lasatint.h> 30 + #include <asm/time.h> 30 31 #include <asm/gdb-stub.h> 31 32 32 33 static volatile int *lasat_int_status = NULL; 33 34 static volatile int *lasat_int_mask = NULL; 34 35 static volatile int lasat_int_mask_shift; 35 - 36 - extern asmlinkage void lasatIRQ(void); 37 36 38 37 void disable_lasat_irq(unsigned int irq_nr) 39 38 { ··· 108 109 return int_status; 109 110 } 110 111 111 - void lasat_hw0_irqdispatch(struct pt_regs *regs) 112 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 112 113 { 113 114 unsigned long int_status; 115 + unsigned int cause = read_c0_cause(); 114 116 int irq; 117 + 118 + if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ 119 + ll_timer_interrupt(7, regs); 120 + return; 121 + } 115 122 116 123 int_status = get_int_status(); 117 124 ··· 151 146 default: 152 147 panic("arch_init_irq: mips_machtype incorrect"); 153 148 } 154 - 155 - /* Now safe to set the exception vector. */ 156 - set_except_vector(0, lasatIRQ); 157 149 158 150 for (i = 0; i <= LASATINT_END; i++) { 159 151 irq_desc[i].status = IRQ_DISABLED;
-69
arch/mips/lasat/lasatIRQ.S
··· 1 - /* 2 - * Carsten Langgaard, carstenl@mips.com 3 - * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. 4 - * 5 - * This program is free software; you can distribute it and/or modify it 6 - * under the terms of the GNU General Public License (Version 2) as 7 - * published by the Free Software Foundation. 8 - * 9 - * This program is distributed in the hope it will be useful, but WITHOUT 10 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 - * for more details. 13 - * 14 - * You should have received a copy of the GNU General Public License along 15 - * with this program; if not, write to the Free Software Foundation, Inc., 16 - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 17 - * 18 - * Interrupt exception dispatch code. 19 - */ 20 - #include <asm/asm.h> 21 - #include <asm/mipsregs.h> 22 - #include <asm/regdef.h> 23 - #include <asm/stackframe.h> 24 - 25 - .text 26 - .set noreorder 27 - .align 5 28 - NESTED(lasatIRQ, PT_SIZE, sp) 29 - .set noat 30 - SAVE_ALL 31 - CLI 32 - .set at 33 - .set noreorder 34 - 35 - mfc0 s0, CP0_CAUSE # get irq mask 36 - 37 - /* First we check for r4k counter/timer IRQ. */ 38 - andi a0, s0, CAUSEF_IP7 39 - beq a0, zero, 1f 40 - andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt 41 - 42 - /* Wheee, a timer interrupt. */ 43 - li a0, 7 44 - jal ll_timer_interrupt 45 - move a1, sp 46 - 47 - j ret_from_irq 48 - nop 49 - 50 - 1: 51 - /* Wheee, combined hardware level zero interrupt. */ 52 - jal lasat_hw0_irqdispatch 53 - move a0, sp # delay slot 54 - 55 - j ret_from_irq 56 - nop # delay slot 57 - 58 - 1: 59 - /* 60 - * Here by mistake? This is possible, what can happen is that by the 61 - * time we take the exception the IRQ pin goes low, so just leave if 62 - * this is the case. 63 - */ 64 - move a1,s0 65 - mfc0 a1, CP0_EPC 66 - 67 - j ret_from_irq 68 - nop 69 - END(lasatIRQ)
+1 -1
arch/mips/mips-boards/atlas/Makefile
··· 16 16 # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 17 17 # 18 18 19 - obj-y := atlas_int.o atlas-irq.o atlas_setup.o 19 + obj-y := atlas_int.o atlas_setup.o 20 20 obj-$(CONFIG_KGDB) += atlas_gdb.o
-120
arch/mips/mips-boards/atlas/atlas-irq.S
··· 1 - /* 2 - * Carsten Langgaard, carstenl@mips.com 3 - * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. 4 - * 5 - * This program is free software; you can distribute it and/or modify it 6 - * under the terms of the GNU General Public License (Version 2) as 7 - * published by the Free Software Foundation. 8 - * 9 - * This program is distributed in the hope it will be useful, but WITHOUT 10 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 - * for more details. 13 - * 14 - * You should have received a copy of the GNU General Public License along 15 - * with this program; if not, write to the Free Software Foundation, Inc., 16 - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 17 - * 18 - * Interrupt exception dispatch code. 19 - */ 20 - #include <linux/config.h> 21 - 22 - #include <asm/asm.h> 23 - #include <asm/mipsregs.h> 24 - #include <asm/regdef.h> 25 - #include <asm/stackframe.h> 26 - #include <asm/mips-boards/atlasint.h> 27 - 28 - /* 29 - * Furthermore, the IRQs on the MIPS board look basically (barring software 30 - * IRQs which we don't use at all and all external interrupt sources are 31 - * combined together on hardware interrupt 0 (MIPS IRQ 2)) like: 32 - * 33 - * MIPS IRQ Source 34 - * -------- ------ 35 - * 0 Software (ignored) 36 - * 1 Software (ignored) 37 - * 2 Combined hardware interrupt (hw0) 38 - * 3 Hardware (ignored) 39 - * 4 Hardware (ignored) 40 - * 5 Hardware (ignored) 41 - * 6 Hardware (ignored) 42 - * 7 R4k timer (what we use) 43 - * 44 - * Note: On the SEAD board thing are a little bit different. 45 - * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired 46 - * wired to UART1. 47 - * 48 - * We handle the IRQ according to _our_ priority which is: 49 - * 50 - * Highest ---- R4k Timer 51 - * Lowest ---- Combined hardware interrupt 52 - * 53 - * then we just return, if multiple IRQs are pending then we will just take 54 - * another exception, big deal. 55 - */ 56 - 57 - .text 58 - .set noreorder 59 - .set noat 60 - .align 5 61 - NESTED(mipsIRQ, PT_SIZE, sp) 62 - SAVE_ALL 63 - CLI 64 - .set at 65 - 66 - mfc0 s0, CP0_CAUSE # get irq bits 67 - mfc0 s1, CP0_STATUS # get irq mask 68 - andi s0, ST0_IM # CAUSE.CE may be non-zero! 69 - and s0, s1 70 - 71 - #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 72 - .set mips32 73 - clz a0, s0 74 - .set mips0 75 - negu a0 76 - addu a0, 31-CAUSEB_IP 77 - bltz a0, spurious 78 - #else 79 - beqz s0, spurious 80 - li a0, 7 81 - 82 - and t0, s0, 0xf000 83 - sltiu t0, t0, 1 84 - sll t0, 2 85 - subu a0, t0 86 - sll s0, t0 87 - 88 - and t0, s0, 0xc000 89 - sltiu t0, t0, 1 90 - sll t0, 1 91 - subu a0, t0 92 - sll s0, t0 93 - 94 - and t0, s0, 0x8000 95 - sltiu t0, t0, 1 96 - # sll t0, 0 97 - subu a0, t0 98 - # sll s0, t0 99 - #endif 100 - 101 - li a1, MIPSCPU_INT_ATLAS 102 - bne a0, a1, 1f 103 - addu a0, MIPSCPU_INT_BASE 104 - 105 - jal atlas_hw0_irqdispatch 106 - move a0, sp 107 - 108 - j ret_from_irq 109 - nop 110 - 111 - 1: jal do_IRQ 112 - move a1, sp 113 - 114 - j ret_from_irq 115 - nop 116 - 117 - spurious: 118 - j spurious_interrupt 119 - nop 120 - END(mipsIRQ)
+86 -6
arch/mips/mips-boards/atlas/atlas_int.c
··· 39 39 40 40 static struct atlas_ictrl_regs *atlas_hw0_icregs; 41 41 42 - extern asmlinkage void mipsIRQ(void); 43 - 44 42 #if 0 45 43 #define DEBUG_INT(x...) printk(x) 46 44 #else ··· 96 98 return b; 97 99 } 98 100 99 - void atlas_hw0_irqdispatch(struct pt_regs *regs) 101 + static inline void atlas_hw0_irqdispatch(struct pt_regs *regs) 100 102 { 101 103 unsigned long int_status; 102 104 int irq; ··· 114 116 do_IRQ(irq, regs); 115 117 } 116 118 119 + static inline int clz(unsigned long x) 120 + { 121 + __asm__ ( 122 + " .set push \n" 123 + " .set mips32 \n" 124 + " clz %0, %1 \n" 125 + " .set pop \n" 126 + : "=r" (x) 127 + : "r" (x)); 128 + 129 + return x; 130 + } 131 + 132 + /* 133 + * Version of ffs that only looks at bits 12..15. 134 + */ 135 + static inline unsigned int irq_ffs(unsigned int pending) 136 + { 137 + #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 138 + return -clz(pending) + 31 - CAUSEB_IP; 139 + #else 140 + unsigned int a0 = 7; 141 + unsigned int t0; 142 + 143 + t0 = s0 & 0xf000; 144 + t0 = t0 < 1; 145 + t0 = t0 << 2; 146 + a0 = a0 - t0; 147 + s0 = s0 << t0; 148 + 149 + t0 = s0 & 0xc000; 150 + t0 = t0 < 1; 151 + t0 = t0 << 1; 152 + a0 = a0 - t0; 153 + s0 = s0 << t0; 154 + 155 + t0 = s0 & 0x8000; 156 + t0 = t0 < 1; 157 + //t0 = t0 << 2; 158 + a0 = a0 - t0; 159 + //s0 = s0 << t0; 160 + 161 + return a0; 162 + #endif 163 + } 164 + 165 + /* 166 + * IRQs on the Atlas board look basically (barring software IRQs which we 167 + * don't use at all and all external interrupt sources are combined together 168 + * on hardware interrupt 0 (MIPS IRQ 2)) like: 169 + * 170 + * MIPS IRQ Source 171 + * -------- ------ 172 + * 0 Software (ignored) 173 + * 1 Software (ignored) 174 + * 2 Combined hardware interrupt (hw0) 175 + * 3 Hardware (ignored) 176 + * 4 Hardware (ignored) 177 + * 5 Hardware (ignored) 178 + * 6 Hardware (ignored) 179 + * 7 R4k timer (what we use) 180 + * 181 + * We handle the IRQ according to _our_ priority which is: 182 + * 183 + * Highest ---- R4k Timer 184 + * Lowest ---- Combined hardware interrupt 185 + * 186 + * then we just return, if multiple IRQs are pending then we will just take 187 + * another exception, big deal. 188 + */ 189 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 190 + { 191 + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 192 + int irq; 193 + 194 + irq = irq_ffs(pending); 195 + 196 + if (irq == MIPSCPU_INT_ATLAS) 197 + atlas_hw0_irqdispatch(regs); 198 + else if (irq > 0) 199 + do_IRQ(MIPSCPU_INT_BASE + irq, regs); 200 + else 201 + spurious_interrupt(regs); 202 + } 203 + 117 204 void __init arch_init_irq(void) 118 205 { 119 206 int i; ··· 210 127 * the interrupt reset reg. 211 128 */ 212 129 atlas_hw0_icregs->intrsten = 0xffffffff; 213 - 214 - /* Now safe to set the exception vector. */ 215 - set_except_vector(0, mipsIRQ); 216 130 217 131 for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { 218 132 irq_desc[i].status = IRQ_DISABLED;
+1 -1
arch/mips/mips-boards/malta/Makefile
··· 19 19 # under Linux. 20 20 # 21 21 22 - obj-y := malta_int.o malta-irq.o malta_setup.o 22 + obj-y := malta_int.o malta_setup.o
-122
arch/mips/mips-boards/malta/malta-irq.S
··· 1 - /* 2 - * Carsten Langgaard, carstenl@mips.com 3 - * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. 4 - * 5 - * ######################################################################## 6 - * 7 - * This program is free software; you can distribute it and/or modify it 8 - * under the terms of the GNU General Public License (Version 2) as 9 - * published by the Free Software Foundation. 10 - * 11 - * This program is distributed in the hope it will be useful, but WITHOUT 12 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 - * for more details. 15 - * 16 - * You should have received a copy of the GNU General Public License along 17 - * with this program; if not, write to the Free Software Foundation, Inc., 18 - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 19 - * 20 - * ######################################################################## 21 - * 22 - * Interrupt exception dispatch code. 23 - * 24 - */ 25 - #include <linux/config.h> 26 - 27 - #include <asm/asm.h> 28 - #include <asm/mipsregs.h> 29 - #include <asm/regdef.h> 30 - #include <asm/stackframe.h> 31 - #include <asm/mips-boards/maltaint.h> 32 - 33 - /* 34 - * IRQs on the Malta board look basically (barring software IRQs which we 35 - * don't use at all and all external interrupt sources are combined together 36 - * on hardware interrupt 0 (MIPS IRQ 2)) like: 37 - * 38 - * MIPS IRQ Source 39 - * -------- ------ 40 - * 0 Software (ignored) 41 - * 1 Software (ignored) 42 - * 2 Combined hardware interrupt (hw0) 43 - * 3 Hardware (ignored) 44 - * 4 Hardware (ignored) 45 - * 5 Hardware (ignored) 46 - * 6 Hardware (ignored) 47 - * 7 R4k timer (what we use) 48 - * 49 - * We handle the IRQ according to _our_ priority which is: 50 - * 51 - * Highest ---- R4k Timer 52 - * Lowest ---- Combined hardware interrupt 53 - * 54 - * then we just return, if multiple IRQs are pending then we will just take 55 - * another exception, big deal. 56 - */ 57 - 58 - .text 59 - .set noreorder 60 - .set noat 61 - .align 5 62 - NESTED(mipsIRQ, PT_SIZE, sp) 63 - SAVE_ALL 64 - CLI 65 - .set at 66 - 67 - mfc0 s0, CP0_CAUSE # get irq bits 68 - mfc0 s1, CP0_STATUS # get irq mask 69 - andi s0, ST0_IM # CAUSE.CE may be non-zero! 70 - and s0, s1 71 - 72 - #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 73 - .set mips32 74 - clz a0, s0 75 - .set mips0 76 - negu a0 77 - addu a0, 31-CAUSEB_IP 78 - bltz a0, spurious 79 - #else 80 - beqz s0, spurious 81 - li a0, 7 82 - 83 - and t0, s0, 0xf000 84 - sltiu t0, t0, 1 85 - sll t0, 2 86 - subu a0, t0 87 - sll s0, t0 88 - 89 - and t0, s0, 0xc000 90 - sltiu t0, t0, 1 91 - sll t0, 1 92 - subu a0, t0 93 - sll s0, t0 94 - 95 - and t0, s0, 0x8000 96 - sltiu t0, t0, 1 97 - # sll t0, 0 98 - subu a0, t0 99 - # sll s0, t0 100 - #endif 101 - 102 - li a1, MIPSCPU_INT_I8259A 103 - bne a0, a1, 1f 104 - addu a0, MIPSCPU_INT_BASE 105 - 106 - jal malta_hw0_irqdispatch 107 - move a0, sp 108 - 109 - j ret_from_irq 110 - nop 111 - 1: 112 - 113 - jal do_IRQ 114 - move a1, sp 115 - 116 - j ret_from_irq 117 - nop 118 - 119 - spurious: 120 - j spurious_interrupt 121 - nop 122 - END(mipsIRQ)
+87 -4
arch/mips/mips-boards/malta/malta_int.c
··· 40 40 #include <asm/mips-boards/msc01_pci.h> 41 41 #include <asm/msc01_ic.h> 42 42 43 - extern asmlinkage void mipsIRQ(void); 44 43 extern void mips_timer_interrupt(void); 45 44 46 45 static DEFINE_SPINLOCK(mips_irq_lock); ··· 113 114 return irq; 114 115 } 115 116 116 - void malta_hw0_irqdispatch(struct pt_regs *regs) 117 + static void malta_hw0_irqdispatch(struct pt_regs *regs) 117 118 { 118 119 int irq; 119 120 ··· 181 182 die("CoreHi interrupt", regs); 182 183 } 183 184 185 + static inline int clz(unsigned long x) 186 + { 187 + __asm__ ( 188 + " .set push \n" 189 + " .set mips32 \n" 190 + " clz %0, %1 \n" 191 + " .set pop \n" 192 + : "=r" (x) 193 + : "r" (x)); 194 + 195 + return x; 196 + } 197 + 198 + /* 199 + * Version of ffs that only looks at bits 12..15. 200 + */ 201 + static inline unsigned int irq_ffs(unsigned int pending) 202 + { 203 + #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 204 + return -clz(pending) + 31 - CAUSEB_IP; 205 + #else 206 + unsigned int a0 = 7; 207 + unsigned int t0; 208 + 209 + t0 = s0 & 0xf000; 210 + t0 = t0 < 1; 211 + t0 = t0 << 2; 212 + a0 = a0 - t0; 213 + s0 = s0 << t0; 214 + 215 + t0 = s0 & 0xc000; 216 + t0 = t0 < 1; 217 + t0 = t0 << 1; 218 + a0 = a0 - t0; 219 + s0 = s0 << t0; 220 + 221 + t0 = s0 & 0x8000; 222 + t0 = t0 < 1; 223 + //t0 = t0 << 2; 224 + a0 = a0 - t0; 225 + //s0 = s0 << t0; 226 + 227 + return a0; 228 + #endif 229 + } 230 + 231 + /* 232 + * IRQs on the Malta board look basically (barring software IRQs which we 233 + * don't use at all and all external interrupt sources are combined together 234 + * on hardware interrupt 0 (MIPS IRQ 2)) like: 235 + * 236 + * MIPS IRQ Source 237 + * -------- ------ 238 + * 0 Software (ignored) 239 + * 1 Software (ignored) 240 + * 2 Combined hardware interrupt (hw0) 241 + * 3 Hardware (ignored) 242 + * 4 Hardware (ignored) 243 + * 5 Hardware (ignored) 244 + * 6 Hardware (ignored) 245 + * 7 R4k timer (what we use) 246 + * 247 + * We handle the IRQ according to _our_ priority which is: 248 + * 249 + * Highest ---- R4k Timer 250 + * Lowest ---- Combined hardware interrupt 251 + * 252 + * then we just return, if multiple IRQs are pending then we will just take 253 + * another exception, big deal. 254 + */ 255 + 256 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 257 + { 258 + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 259 + int irq; 260 + 261 + irq = irq_ffs(pending); 262 + 263 + if (irq == MIPSCPU_INT_I8259A) 264 + malta_hw0_irqdispatch(regs); 265 + else if (irq > 0) 266 + do_IRQ(MIPSCPU_INT_BASE + irq, regs); 267 + else 268 + spurious_interrupt(regs); 269 + } 270 + 184 271 static struct irqaction i8259irq = { 185 272 .handler = no_action, 186 273 .name = "XT-PIC cascade" ··· 299 214 300 215 void __init arch_init_irq(void) 301 216 { 302 - set_except_vector(0, mipsIRQ); 303 217 init_i8259_irqs(); 304 218 305 219 if (!cpu_has_veic) ··· 329 245 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); 330 246 } 331 247 else { 332 - set_except_vector(0, mipsIRQ); 333 248 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); 334 249 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); 335 250 }
+1 -1
arch/mips/mips-boards/sead/Makefile
··· 23 23 # under Linux. 24 24 # 25 25 26 - obj-y := sead_int.o sead-irq.o sead_setup.o 26 + obj-y := sead_int.o sead_setup.o
-111
arch/mips/mips-boards/sead/sead-irq.S
··· 1 - /* 2 - * Carsten Langgaard, carstenl@mips.com 3 - * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. 4 - * 5 - * ######################################################################## 6 - * 7 - * This program is free software; you can distribute it and/or modify it 8 - * under the terms of the GNU General Public License (Version 2) as 9 - * published by the Free Software Foundation. 10 - * 11 - * This program is distributed in the hope it will be useful, but WITHOUT 12 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 - * for more details. 15 - * 16 - * You should have received a copy of the GNU General Public License along 17 - * with this program; if not, write to the Free Software Foundation, Inc., 18 - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 19 - * 20 - * ######################################################################## 21 - * 22 - * Interrupt exception dispatch code. 23 - * 24 - */ 25 - #include <linux/config.h> 26 - 27 - #include <asm/asm.h> 28 - #include <asm/mipsregs.h> 29 - #include <asm/regdef.h> 30 - #include <asm/stackframe.h> 31 - #include <asm/mips-boards/seadint.h> 32 - 33 - /* 34 - * IRQs on the SEAD board look basically are combined together on hardware 35 - * interrupt 0 (MIPS IRQ 2)) like: 36 - * 37 - * MIPS IRQ Source 38 - * -------- ------ 39 - * 0 Software (ignored) 40 - * 1 Software (ignored) 41 - * 2 UART0 (hw0) 42 - * 3 UART1 (hw1) 43 - * 4 Hardware (ignored) 44 - * 5 Hardware (ignored) 45 - * 6 Hardware (ignored) 46 - * 7 R4k timer (what we use) 47 - * 48 - * We handle the IRQ according to _our_ priority which is: 49 - * 50 - * Highest ---- R4k Timer 51 - * Lowest ---- Combined hardware interrupt 52 - * 53 - * then we just return, if multiple IRQs are pending then we will just take 54 - * another exception, big deal. 55 - */ 56 - 57 - .text 58 - .set noreorder 59 - .set noat 60 - .align 5 61 - NESTED(mipsIRQ, PT_SIZE, sp) 62 - SAVE_ALL 63 - CLI 64 - .set at 65 - 66 - mfc0 s0, CP0_CAUSE # get irq bits 67 - mfc0 s1, CP0_STATUS # get irq mask 68 - andi s0, ST0_IM # CAUSE.CE may be non-zero! 69 - and s0, s1 70 - 71 - #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 72 - .set mips32 73 - clz a0, s0 74 - .set mips0 75 - negu a0 76 - addu a0, 31-CAUSEB_IP 77 - bltz a0, spurious 78 - #else 79 - beqz s0, spurious 80 - li a0, 7 81 - 82 - and t0, s0, 0xf000 83 - sltiu t0, t0, 1 84 - sll t0, 2 85 - subu a0, t0 86 - sll s0, t0 87 - 88 - and t0, s0, 0xc000 89 - sltiu t0, t0, 1 90 - sll t0, 1 91 - subu a0, t0 92 - sll s0, t0 93 - 94 - and t0, s0, 0x8000 95 - sltiu t0, t0, 1 96 - # sll t0, 0 97 - subu a0, t0 98 - # sll s0, t0 99 - #endif 100 - 101 - addu a0, MIPSCPU_INT_BASE 102 - jal do_IRQ 103 - move a1, sp 104 - 105 - j ret_from_irq 106 - nop 107 - 108 - spurious: 109 - j spurious_interrupt 110 - nop 111 - END(mipsIRQ)
+82 -4
arch/mips/mips-boards/sead/sead_int.c
··· 24 24 #include <linux/irq.h> 25 25 26 26 #include <asm/irq_cpu.h> 27 + #include <asm/mipsregs.h> 27 28 #include <asm/system.h> 28 29 29 30 #include <asm/mips-boards/seadint.h> 30 31 31 - extern asmlinkage void mipsIRQ(void); 32 + static inline int clz(unsigned long x) 33 + { 34 + __asm__ ( 35 + " .set push \n" 36 + " .set mips32 \n" 37 + " clz %0, %1 \n" 38 + " .set pop \n" 39 + : "=r" (x) 40 + : "r" (x)); 41 + 42 + return x; 43 + } 44 + 45 + /* 46 + * Version of ffs that only looks at bits 12..15. 47 + */ 48 + static inline unsigned int irq_ffs(unsigned int pending) 49 + { 50 + #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 51 + return -clz(pending) + 31 - CAUSEB_IP; 52 + #else 53 + unsigned int a0 = 7; 54 + unsigned int t0; 55 + 56 + t0 = s0 & 0xf000; 57 + t0 = t0 < 1; 58 + t0 = t0 << 2; 59 + a0 = a0 - t0; 60 + s0 = s0 << t0; 61 + 62 + t0 = s0 & 0xc000; 63 + t0 = t0 < 1; 64 + t0 = t0 << 1; 65 + a0 = a0 - t0; 66 + s0 = s0 << t0; 67 + 68 + t0 = s0 & 0x8000; 69 + t0 = t0 < 1; 70 + //t0 = t0 << 2; 71 + a0 = a0 - t0; 72 + //s0 = s0 << t0; 73 + 74 + return a0; 75 + #endif 76 + } 77 + 78 + /* 79 + * IRQs on the SEAD board look basically are combined together on hardware 80 + * interrupt 0 (MIPS IRQ 2)) like: 81 + * 82 + * MIPS IRQ Source 83 + * -------- ------ 84 + * 0 Software (ignored) 85 + * 1 Software (ignored) 86 + * 2 UART0 (hw0) 87 + * 3 UART1 (hw1) 88 + * 4 Hardware (ignored) 89 + * 5 Hardware (ignored) 90 + * 6 Hardware (ignored) 91 + * 7 R4k timer (what we use) 92 + * 93 + * We handle the IRQ according to _our_ priority which is: 94 + * 95 + * Highest ---- R4k Timer 96 + * Lowest ---- Combined hardware interrupt 97 + * 98 + * then we just return, if multiple IRQs are pending then we will just take 99 + * another exception, big deal. 100 + */ 101 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 102 + { 103 + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 104 + int irq; 105 + 106 + irq = irq_ffs(pending); 107 + 108 + if (irq >= 0) 109 + do_IRQ(MIPSCPU_INT_BASE + irq, regs); 110 + else 111 + spurious_interrupt(regs); 112 + } 32 113 33 114 void __init arch_init_irq(void) 34 115 { 35 116 mips_cpu_irq_init(MIPSCPU_INT_BASE); 36 - 37 - /* Now safe to set the exception vector. */ 38 - set_except_vector(0, mipsIRQ); 39 117 }
+59 -5
arch/mips/mips-boards/sim/sim_int.c
··· 25 25 26 26 extern void mips_cpu_irq_init(int); 27 27 28 - extern asmlinkage void simIRQ(void); 28 + static inline int clz(unsigned long x) 29 + { 30 + __asm__ ( 31 + " .set push \n" 32 + " .set mips32 \n" 33 + " clz %0, %1 \n" 34 + " .set pop \n" 35 + : "=r" (x) 36 + : "r" (x)); 29 37 30 - asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs) 38 + return x; 39 + } 40 + 41 + /* 42 + * Version of ffs that only looks at bits 12..15. 43 + */ 44 + static inline unsigned int irq_ffs(unsigned int pending) 45 + { 46 + #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 47 + return -clz(pending) + 31 - CAUSEB_IP; 48 + #else 49 + unsigned int a0 = 7; 50 + unsigned int t0; 51 + 52 + t0 = s0 & 0xf000; 53 + t0 = t0 < 1; 54 + t0 = t0 << 2; 55 + a0 = a0 - t0; 56 + s0 = s0 << t0; 57 + 58 + t0 = s0 & 0xc000; 59 + t0 = t0 < 1; 60 + t0 = t0 << 1; 61 + a0 = a0 - t0; 62 + s0 = s0 << t0; 63 + 64 + t0 = s0 & 0x8000; 65 + t0 = t0 < 1; 66 + //t0 = t0 << 2; 67 + a0 = a0 - t0; 68 + //s0 = s0 << t0; 69 + 70 + return a0; 71 + #endif 72 + } 73 + 74 + static inline void sim_hw0_irqdispatch(struct pt_regs *regs) 31 75 { 32 76 do_IRQ(2, regs); 33 77 } 34 78 79 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 80 + { 81 + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 82 + int irq; 83 + 84 + irq = irq_ffs(pending); 85 + 86 + if (irq > 0) 87 + do_IRQ(MIPSCPU_INT_BASE + irq, regs); 88 + else 89 + spurious_interrupt(regs); 90 + } 91 + 35 92 void __init arch_init_irq(void) 36 93 { 37 - /* Now safe to set the exception vector. */ 38 - set_except_vector(0, simIRQ); 39 - 40 94 mips_cpu_irq_init(MIPSCPU_INT_BASE); 41 95 }
+1 -1
arch/mips/momentum/jaguar_atx/Makefile
··· 6 6 # unless it's something special (ie not a .c file). 7 7 # 8 8 9 - obj-y += int-handler.o irq.o prom.o reset.o setup.o 9 + obj-y += irq.o prom.o reset.o setup.o 10 10 11 11 obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o 12 12 obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
-128
arch/mips/momentum/jaguar_atx/int-handler.S
··· 1 - /* 2 - * Copyright 2002 Momentum Computer Inc. 3 - * Author: Matthew Dharm <mdharm@momenco.com> 4 - * 5 - * Based on work: 6 - * Copyright 2001 MontaVista Software Inc. 7 - * Author: jsun@mvista.com or jsun@junsun.net 8 - * 9 - * First-level interrupt dispatcher for Jaguar-ATX board. 10 - * 11 - * This program is free software; you can redistribute it and/or modify it 12 - * under the terms of the GNU General Public License as published by the 13 - * Free Software Foundation; either version 2 of the License, or (at your 14 - * option) any later version. 15 - */ 16 - #include <asm/asm.h> 17 - #include <asm/mipsregs.h> 18 - #include <asm/addrspace.h> 19 - #include <asm/regdef.h> 20 - #include <asm/stackframe.h> 21 - 22 - /* 23 - * First level interrupt dispatcher for Ocelot-CS board 24 - */ 25 - .align 5 26 - NESTED(jaguar_handle_int, PT_SIZE, sp) 27 - SAVE_ALL 28 - CLI 29 - .set at 30 - mfc0 t0, CP0_CAUSE 31 - mfc0 t2, CP0_STATUS 32 - 33 - and t0, t2 34 - 35 - andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ 36 - bnez t1, ll_sw0_irq 37 - andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ 38 - bnez t1, ll_sw1_irq 39 - andi t1, t0, STATUSF_IP2 /* int0 hardware line */ 40 - bnez t1, ll_pcixa_irq 41 - andi t1, t0, STATUSF_IP3 /* int1 hardware line */ 42 - bnez t1, ll_pcixb_irq 43 - andi t1, t0, STATUSF_IP4 /* int2 hardware line */ 44 - bnez t1, ll_pcia_irq 45 - andi t1, t0, STATUSF_IP5 /* int3 hardware line */ 46 - bnez t1, ll_pcib_irq 47 - andi t1, t0, STATUSF_IP6 /* int4 hardware line */ 48 - bnez t1, ll_uart_irq 49 - andi t1, t0, STATUSF_IP7 /* cpu timer */ 50 - bnez t1, ll_cputimer_irq 51 - 52 - nop 53 - nop 54 - 55 - /* now look at extended interrupts */ 56 - mfc0 t0, CP0_CAUSE 57 - cfc0 t1, CP0_S1_INTCONTROL 58 - 59 - /* shift the mask 8 bits left to line up the bits */ 60 - sll t2, t1, 8 61 - 62 - and t0, t2 63 - srl t0, t0, 16 64 - 65 - andi t1, t0, STATUSF_IP8 /* int6 hardware line */ 66 - bnez t1, ll_mv64340_decode_irq 67 - 68 - nop 69 - nop 70 - 71 - .set reorder 72 - 73 - /* wrong alarm or masked ... */ 74 - j spurious_interrupt 75 - nop 76 - END(jaguar_handle_int) 77 - 78 - .align 5 79 - ll_sw0_irq: 80 - li a0, 0 81 - move a1, sp 82 - jal do_IRQ 83 - j ret_from_irq 84 - ll_sw1_irq: 85 - li a0, 1 86 - move a1, sp 87 - jal do_IRQ 88 - j ret_from_irq 89 - ll_pcixa_irq: 90 - li a0, 2 91 - move a1, sp 92 - jal do_IRQ 93 - j ret_from_irq 94 - 95 - ll_pcixb_irq: 96 - li a0, 3 97 - move a1, sp 98 - jal do_IRQ 99 - j ret_from_irq 100 - 101 - ll_pcia_irq: 102 - li a0, 4 103 - move a1, sp 104 - jal do_IRQ 105 - j ret_from_irq 106 - 107 - ll_pcib_irq: 108 - li a0, 5 109 - move a1, sp 110 - jal do_IRQ 111 - j ret_from_irq 112 - 113 - ll_uart_irq: 114 - li a0, 6 115 - move a1, sp 116 - jal do_IRQ 117 - j ret_from_irq 118 - 119 - ll_cputimer_irq: 120 - li a0, 7 121 - move a1, sp 122 - jal ll_timer_interrupt 123 - j ret_from_irq 124 - 125 - ll_mv64340_decode_irq: 126 - move a0, sp 127 - jal ll_mv64340_irq 128 - j ret_from_irq
+31 -4
arch/mips/momentum/jaguar_atx/irq.c
··· 10 10 * Copyright 2001 MontaVista Software Inc. 11 11 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net 12 12 * 13 - * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) 13 + * Copyright (C) 2000, 01, 06 Ralf Baechle (ralf@linux-mips.org) 14 14 * 15 15 * This program is free software; you can redistribute it and/or modify it 16 16 * under the terms of the GNU General Public License as published by the ··· 38 38 #include <linux/types.h> 39 39 #include <asm/irq_cpu.h> 40 40 #include <asm/mipsregs.h> 41 + #include <asm/time.h> 41 42 42 - extern asmlinkage void jaguar_handle_int(void); 43 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 44 + { 45 + unsigned int pending = read_c0_cause() & read_c0_status(); 46 + 47 + if (pending & STATUSF_IP0) 48 + do_IRQ(0, regs); 49 + else if (pending & STATUSF_IP1) 50 + do_IRQ(1, regs); 51 + else if (pending & STATUSF_IP2) 52 + do_IRQ(2, regs); 53 + else if (pending & STATUSF_IP3) 54 + do_IRQ(3, regs); 55 + else if (pending & STATUSF_IP4) 56 + do_IRQ(4, regs); 57 + else if (pending & STATUSF_IP5) 58 + do_IRQ(5, regs); 59 + else if (pending & STATUSF_IP6) 60 + do_IRQ(6, regs); 61 + else if (pending & STATUSF_IP7) 62 + ll_timer_interrupt(7, regs); 63 + else { 64 + /* 65 + * Now look at the extended interrupts 66 + */ 67 + pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; 68 + if (pending & STATUSF_IP8) 69 + ll_mv64340_irq(regs); 70 + } 71 + } 43 72 44 73 static struct irqaction cascade_mv64340 = { 45 74 no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL ··· 82 53 */ 83 54 clear_c0_status(ST0_IM); 84 55 85 - /* Sets the first-level interrupt dispatcher. */ 86 - set_except_vector(0, jaguar_handle_int); 87 56 mips_cpu_irq_init(0); 88 57 rm7k_cpu_irq_init(8); 89 58
+1 -1
arch/mips/momentum/ocelot_3/Makefile
··· 5 5 # removes any old dependencies. DON'T put your own dependencies here 6 6 # unless it's something special (ie not a .c file). 7 7 # 8 - obj-y += int-handler.o irq.o prom.o reset.o setup.o 8 + obj-y += irq.o prom.o reset.o setup.o
-139
arch/mips/momentum/ocelot_3/int-handler.S
··· 1 - /* 2 - * Copyright 2002 Momentum Computer Inc. 3 - * Author: Matthew Dharm <mdharm@momenco.com> 4 - * 5 - * Copyright 2001 MontaVista Software Inc. 6 - * Author: jsun@mvista.com or jsun@junsun.net 7 - * 8 - * Copyright 2004 PMC-Sierra 9 - * Author: Manish Lachwani (lachwani@pmc-sierra.com) 10 - * 11 - * Copyright (C) 2004 MontaVista Software Inc. 12 - * Author: Manish Lachwani, mlachwani@mvista.com 13 - * 14 - * First-level interrupt dispatcher for Ocelot-3 board. 15 - * 16 - * This program is free software; you can redistribute it and/or modify it 17 - * under the terms of the GNU General Public License as published by the 18 - * Free Software Foundation; either version 2 of the License, or (at your 19 - * option) any later version. 20 - */ 21 - #include <asm/asm.h> 22 - #include <asm/mipsregs.h> 23 - #include <asm/addrspace.h> 24 - #include <asm/regdef.h> 25 - #include <asm/stackframe.h> 26 - 27 - /* 28 - * First level interrupt dispatcher for Ocelot-3 board 29 - */ 30 - .align 5 31 - NESTED(ocelot3_handle_int, PT_SIZE, sp) 32 - SAVE_ALL 33 - CLI 34 - .set at 35 - 36 - mfc0 t0, CP0_CAUSE 37 - mfc0 t2, CP0_STATUS 38 - 39 - and t0, t2 40 - 41 - andi t1, t0, STATUSF_IP0 /* sw0 software interrupt (IRQ0) */ 42 - bnez t1, ll_sw0_irq 43 - 44 - andi t1, t0, STATUSF_IP1 /* sw1 software interrupt (IRQ1) */ 45 - bnez t1, ll_sw1_irq 46 - 47 - andi t1, t0, STATUSF_IP2 /* int0 hardware line (IRQ2) */ 48 - bnez t1, ll_pci0slot1_irq 49 - 50 - andi t1, t0, STATUSF_IP3 /* int1 hardware line (IRQ3) */ 51 - bnez t1, ll_pci0slot2_irq 52 - 53 - andi t1, t0, STATUSF_IP4 /* int2 hardware line (IRQ4) */ 54 - bnez t1, ll_pci1slot1_irq 55 - 56 - andi t1, t0, STATUSF_IP5 /* int3 hardware line (IRQ5) */ 57 - bnez t1, ll_pci1slot2_irq 58 - 59 - andi t1, t0, STATUSF_IP6 /* int4 hardware line (IRQ6) */ 60 - bnez t1, ll_uart_irq 61 - 62 - andi t1, t0, STATUSF_IP7 /* cpu timer (IRQ7) */ 63 - bnez t1, ll_cputimer_irq 64 - 65 - /* now look at extended interrupts */ 66 - mfc0 t0, CP0_CAUSE 67 - cfc0 t1, CP0_S1_INTCONTROL 68 - 69 - /* shift the mask 8 bits left to line up the bits */ 70 - sll t2, t1, 8 71 - 72 - and t0, t2 73 - srl t0, t0, 16 74 - 75 - andi t1, t0, STATUSF_IP8 /* int6 hardware line (IRQ9) */ 76 - bnez t1, ll_mv64340_decode_irq 77 - 78 - .set reorder 79 - 80 - /* wrong alarm or masked ... */ 81 - jal spurious_interrupt 82 - nop 83 - j ret_from_irq 84 - nop 85 - END(ocelot3_handle_int) 86 - 87 - .align 5 88 - ll_sw0_irq: 89 - li a0, 0 /* IRQ 1 */ 90 - move a1, sp 91 - jal do_IRQ 92 - j ret_from_irq 93 - ll_sw1_irq: 94 - li a0, 1 /* IRQ 2 */ 95 - move a1, sp 96 - jal do_IRQ 97 - j ret_from_irq 98 - 99 - ll_pci0slot1_irq: 100 - li a0, 2 /* IRQ 3 */ 101 - move a1, sp 102 - jal do_IRQ 103 - j ret_from_irq 104 - 105 - ll_pci0slot2_irq: 106 - li a0, 3 /* IRQ 4 */ 107 - move a1, sp 108 - jal do_IRQ 109 - j ret_from_irq 110 - 111 - ll_pci1slot1_irq: 112 - li a0, 4 /* IRQ 5 */ 113 - move a1, sp 114 - jal do_IRQ 115 - j ret_from_irq 116 - 117 - ll_pci1slot2_irq: 118 - li a0, 5 /* IRQ 6 */ 119 - move a1, sp 120 - jal do_IRQ 121 - j ret_from_irq 122 - 123 - ll_uart_irq: 124 - li a0, 6 /* IRQ 7 */ 125 - move a1, sp 126 - jal do_IRQ 127 - j ret_from_irq 128 - 129 - ll_cputimer_irq: 130 - li a0, 7 /* IRQ 8 */ 131 - move a1, sp 132 - jal do_IRQ 133 - j ret_from_irq 134 - 135 - ll_mv64340_decode_irq: 136 - move a0, sp 137 - jal ll_mv64340_irq 138 - j ret_from_irq 139 -
+33 -5
arch/mips/momentum/ocelot_3/irq.c
··· 53 53 #include <asm/mipsregs.h> 54 54 #include <asm/system.h> 55 55 56 - extern asmlinkage void ocelot3_handle_int(void); 57 - 58 56 static struct irqaction cascade_mv64340 = { 59 57 no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL 60 58 }; ··· 65 67 */ 66 68 clear_c0_status(ST0_IM | ST0_BEV); 67 69 68 - /* Sets the first-level interrupt dispatcher. */ 69 - set_except_vector(0, ocelot3_handle_int); 70 - mips_cpu_irq_init(0); 71 70 rm7k_cpu_irq_init(8); 72 71 73 72 /* set up the cascading interrupts */ ··· 73 78 74 79 set_c0_status(ST0_IM); /* IE in the status register */ 75 80 81 + } 82 + 83 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 84 + { 85 + unsigned int pending = read_c0_cause() & read_c0_status(); 86 + 87 + if (pending & STATUSF_IP0) 88 + do_IRQ(0, regs); 89 + else if (pending & STATUSF_IP1) 90 + do_IRQ(1, regs); 91 + else if (pending & STATUSF_IP2) 92 + do_IRQ(2, regs); 93 + else if (pending & STATUSF_IP3) 94 + do_IRQ(3, regs); 95 + else if (pending & STATUSF_IP4) 96 + do_IRQ(4, regs); 97 + else if (pending & STATUSF_IP5) 98 + do_IRQ(5, regs); 99 + else if (pending & STATUSF_IP6) 100 + do_IRQ(6, regs); 101 + else if (pending & STATUSF_IP7) 102 + do_IRQ(7, regs); 103 + else { 104 + /* 105 + * Now look at the extended interrupts 106 + */ 107 + pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; 108 + 109 + if (pending & STATUSF_IP8) 110 + ll_mv64340_irq(regs); 111 + else 112 + spurious_interrupt(regs); 113 + } 76 114 }
+1 -1
arch/mips/momentum/ocelot_c/Makefile
··· 2 2 # Makefile for Momentum Computer's Ocelot-C and -CS boards. 3 3 # 4 4 5 - obj-y += cpci-irq.o int-handler.o irq.o prom.o reset.o \ 5 + obj-y += cpci-irq.o irq.o prom.o reset.o \ 6 6 setup.o uart-irq.o 7 7 8 8 obj-$(CONFIG_KGDB) += dbg_io.o
-103
arch/mips/momentum/ocelot_c/int-handler.S
··· 1 - /* 2 - * Copyright 2002 Momentum Computer Inc. 3 - * Author: Matthew Dharm <mdharm@momenco.com> 4 - * 5 - * Copyright 2001 MontaVista Software Inc. 6 - * Author: jsun@mvista.com or jsun@junsun.net 7 - * 8 - * First-level interrupt dispatcher for Ocelot-CS board. 9 - * 10 - * This program is free software; you can redistribute it and/or modify it 11 - * under the terms of the GNU General Public License as published by the 12 - * Free Software Foundation; either version 2 of the License, or (at your 13 - * option) any later version. 14 - */ 15 - #include <asm/asm.h> 16 - #include <asm/mipsregs.h> 17 - #include <asm/addrspace.h> 18 - #include <asm/regdef.h> 19 - #include <asm/stackframe.h> 20 - #include "ocelot_c_fpga.h" 21 - 22 - /* 23 - * First level interrupt dispatcher for Ocelot-CS board 24 - */ 25 - .align 5 26 - NESTED(ocelot_handle_int, PT_SIZE, sp) 27 - SAVE_ALL 28 - CLI 29 - .set at 30 - mfc0 t0, CP0_CAUSE 31 - mfc0 t2, CP0_STATUS 32 - 33 - and t0, t2 34 - 35 - andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ 36 - bnez t1, ll_sw0_irq 37 - andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ 38 - bnez t1, ll_sw1_irq 39 - andi t1, t0, STATUSF_IP2 /* int0 hardware line */ 40 - bnez t1, ll_scsi_irq 41 - andi t1, t0, STATUSF_IP3 /* int1 hardware line */ 42 - bnez t1, ll_uart_decode_irq 43 - andi t1, t0, STATUSF_IP4 /* int2 hardware line */ 44 - bnez t1, ll_pmc_irq 45 - andi t1, t0, STATUSF_IP5 /* int3 hardware line */ 46 - bnez t1, ll_cpci_decode_irq 47 - andi t1, t0, STATUSF_IP6 /* int4 hardware line */ 48 - bnez t1, ll_mv64340_decode_irq 49 - andi t1, t0, STATUSF_IP7 /* cpu timer */ 50 - bnez t1, ll_cputimer_irq 51 - 52 - .set reorder 53 - 54 - /* wrong alarm or masked ... */ 55 - jal spurious_interrupt 56 - nop 57 - j ret_from_irq 58 - END(ocelot_handle_int) 59 - 60 - .align 5 61 - ll_sw0_irq: 62 - li a0, 0 63 - move a1, sp 64 - jal do_IRQ 65 - j ret_from_irq 66 - ll_sw1_irq: 67 - li a0, 1 68 - move a1, sp 69 - jal do_IRQ 70 - j ret_from_irq 71 - ll_scsi_irq: 72 - li a0, 2 73 - move a1, sp 74 - jal do_IRQ 75 - j ret_from_irq 76 - 77 - ll_uart_decode_irq: 78 - move a0, sp 79 - jal ll_uart_irq 80 - j ret_from_irq 81 - 82 - ll_pmc_irq: 83 - li a0, 4 84 - move a1, sp 85 - jal do_IRQ 86 - j ret_from_irq 87 - 88 - ll_cpci_decode_irq: 89 - move a0, sp 90 - jal ll_cpci_irq 91 - j ret_from_irq 92 - 93 - ll_mv64340_decode_irq: 94 - move a0, sp 95 - jal ll_mv64340_irq 96 - j ret_from_irq 97 - 98 - ll_cputimer_irq: 99 - li a0, 7 100 - move a1, sp 101 - jal do_IRQ 102 - j ret_from_irq 103 -
+27 -3
arch/mips/momentum/ocelot_c/irq.c
··· 48 48 #include <asm/mipsregs.h> 49 49 #include <asm/system.h> 50 50 51 - extern asmlinkage void ocelot_handle_int(void); 52 51 extern void uart_irq_init(void); 53 52 extern void cpci_irq_init(void); 54 53 ··· 59 60 no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL 60 61 }; 61 62 63 + extern void ll_uart_irq(struct pt_regs *regs); 64 + extern void ll_cpci_irq(struct pt_regs *regs); 65 + 66 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 67 + { 68 + unsigned int pending = read_c0_cause() & read_c0_status(); 69 + 70 + if (pending & STATUSF_IP0) 71 + do_IRQ(0, regs); 72 + else if (pending & STATUSF_IP1) 73 + do_IRQ(1, regs); 74 + else if (pending & STATUSF_IP2) 75 + do_IRQ(2, regs); 76 + else if (pending & STATUSF_IP3) 77 + ll_uart_irq(regs); 78 + else if (pending & STATUSF_IP4) 79 + do_IRQ(4, regs); 80 + else if (pending & STATUSF_IP5) 81 + ll_cpci_irq(regs); 82 + else if (pending & STATUSF_IP6) 83 + ll_mv64340_irq(regs); 84 + else if (pending & STATUSF_IP7) 85 + do_IRQ(7, regs); 86 + else 87 + spurious_interrupt(regs); 88 + } 89 + 62 90 void __init arch_init_irq(void) 63 91 { 64 92 /* ··· 94 68 */ 95 69 clear_c0_status(ST0_IM); 96 70 97 - /* Sets the first-level interrupt dispatcher. */ 98 - set_except_vector(0, ocelot_handle_int); 99 71 mips_cpu_irq_init(0); 100 72 101 73 /* set up the cascading interrupts */
+1 -1
arch/mips/momentum/ocelot_g/Makefile
··· 2 2 # Makefile for Momentum Computer's Ocelot-G board. 3 3 # 4 4 5 - obj-y += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o 5 + obj-y += irq.o gt-irq.o prom.o reset.o setup.o 6 6 obj-$(CONFIG_KGDB) += dbg_io.o 7 7 8 8 EXTRA_AFLAGS := $(CFLAGS)
-131
arch/mips/momentum/ocelot_g/int-handler.S
··· 1 - /* 2 - * Copyright 2001 MontaVista Software Inc. 3 - * Author: jsun@mvista.com or jsun@junsun.net 4 - * 5 - * First-level interrupt dispatcher for ocelot board. 6 - * 7 - * This program is free software; you can redistribute it and/or modify it 8 - * under the terms of the GNU General Public License as published by the 9 - * Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - */ 12 - #include <asm/asm.h> 13 - #include <asm/mipsregs.h> 14 - #include <asm/addrspace.h> 15 - #include <asm/regdef.h> 16 - #include <asm/stackframe.h> 17 - 18 - /* 19 - * first level interrupt dispatcher for ocelot board - 20 - * We check for the timer first, then check PCI ints A and D. 21 - * Then check for serial IRQ and fall through. 22 - */ 23 - .align 5 24 - NESTED(ocelot_handle_int, PT_SIZE, sp) 25 - SAVE_ALL 26 - CLI 27 - .set at 28 - mfc0 t0, CP0_CAUSE 29 - mfc0 t2, CP0_STATUS 30 - 31 - and t0, t2 32 - 33 - andi t1, t0, STATUSF_IP2 /* int0 hardware line */ 34 - bnez t1, ll_pri_enet_irq 35 - andi t1, t0, STATUSF_IP3 /* int1 hardware line */ 36 - bnez t1, ll_sec_enet_irq 37 - andi t1, t0, STATUSF_IP4 /* int2 hardware line */ 38 - bnez t1, ll_uart_irq 39 - andi t1, t0, STATUSF_IP5 /* int3 hardware line */ 40 - bnez t1, ll_cpci_irq 41 - andi t1, t0, STATUSF_IP6 /* int4 hardware line */ 42 - bnez t1, ll_galileo_p0_irq 43 - andi t1, t0, STATUSF_IP7 /* cpu timer */ 44 - bnez t1, ll_cputimer_irq 45 - 46 - /* now look at the extended interrupts */ 47 - mfc0 t0, CP0_CAUSE 48 - cfc0 t1, CP0_S1_INTCONTROL 49 - 50 - /* shift the mask 8 bits left to line up the bits */ 51 - sll t2, t1, 8 52 - 53 - and t0, t2 54 - srl t0, t0, 16 55 - 56 - andi t1, t0, STATUSF_IP8 /* int6 hardware line */ 57 - bnez t1, ll_galileo_p1_irq 58 - andi t1, t0, STATUSF_IP9 /* int7 hardware line */ 59 - bnez t1, ll_pmc_irq 60 - andi t1, t0, STATUSF_IP10 /* int8 hardware line */ 61 - bnez t1, ll_cpci_abcd_irq 62 - andi t1, t0, STATUSF_IP11 /* int9 hardware line */ 63 - bnez t1, ll_testpoint_irq 64 - 65 - .set reorder 66 - 67 - /* wrong alarm or masked ... */ 68 - j spurious_interrupt 69 - nop 70 - END(ocelot_handle_int) 71 - 72 - .align 5 73 - ll_pri_enet_irq: 74 - li a0, 2 75 - move a1, sp 76 - jal do_IRQ 77 - j ret_from_irq 78 - 79 - ll_sec_enet_irq: 80 - li a0, 3 81 - move a1, sp 82 - jal do_IRQ 83 - j ret_from_irq 84 - 85 - ll_uart_irq: 86 - li a0, 4 87 - move a1, sp 88 - jal do_IRQ 89 - j ret_from_irq 90 - 91 - ll_cpci_irq: 92 - li a0, 5 93 - move a1, sp 94 - jal do_IRQ 95 - j ret_from_irq 96 - 97 - ll_galileo_p0_irq: 98 - li a0, 6 99 - move a1, sp 100 - jal do_IRQ 101 - j ret_from_irq 102 - 103 - ll_cputimer_irq: 104 - li a0, 7 105 - move a1, sp 106 - jal do_IRQ 107 - j ret_from_irq 108 - 109 - ll_galileo_p1_irq: 110 - li a0, 8 111 - move a1, sp 112 - jal do_IRQ 113 - j ret_from_irq 114 - 115 - ll_pmc_irq: 116 - li a0, 9 117 - move a1, sp 118 - jal do_IRQ 119 - j ret_from_irq 120 - 121 - ll_cpci_abcd_irq: 122 - li a0, 10 123 - move a1, sp 124 - jal do_IRQ 125 - j ret_from_irq 126 - 127 - ll_testpoint_irq: 128 - li a0, 11 129 - move a1, sp 130 - jal do_IRQ 131 - j ret_from_irq
+35 -3
arch/mips/momentum/ocelot_g/irq.c
··· 48 48 #include <asm/mipsregs.h> 49 49 #include <asm/system.h> 50 50 51 - extern asmlinkage void ocelot_handle_int(void); 51 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 52 + { 53 + unsigned int pending = read_c0_cause() & read_c0_status(); 54 + 55 + if (pending & STATUSF_IP2) 56 + do_IRQ(2, regs); 57 + else if (pending & STATUSF_IP3) 58 + do_IRQ(3, regs); 59 + else if (pending & STATUSF_IP4) 60 + do_IRQ(4, regs); 61 + else if (pending & STATUSF_IP5) 62 + do_IRQ(5, regs); 63 + else if (pending & STATUSF_IP6) 64 + do_IRQ(6, regs); 65 + else if (pending & STATUSF_IP7) 66 + do_IRQ(7, regs); 67 + else { 68 + /* 69 + * Now look at the extended interrupts 70 + */ 71 + pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; 72 + 73 + if (pending & STATUSF_IP8) 74 + do_IRQ(8, regs); 75 + else if (pending & STATUSF_IP9) 76 + do_IRQ(9, regs); 77 + else if (pending & STATUSF_IP10) 78 + do_IRQ(10, regs); 79 + else if (pending & STATUSF_IP11) 80 + do_IRQ(11, regs); 81 + else 82 + spurious_interrupt(regs); 83 + } 84 + } 85 + 52 86 extern void gt64240_irq_init(void); 53 87 54 88 void __init arch_init_irq(void) ··· 94 60 clear_c0_status(ST0_IM); 95 61 local_irq_disable(); 96 62 97 - /* Sets the first-level interrupt dispatcher. */ 98 - set_except_vector(0, ocelot_handle_int); 99 63 mips_cpu_irq_init(0); 100 64 rm7k_cpu_irq_init(8); 101 65
+1 -1
arch/mips/philips/pnx8550/common/Makefile
··· 22 22 # under Linux. 23 23 # 24 24 25 - obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o 25 + obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o 26 26 obj-$(CONFIG_PCI) += pci.o 27 27 obj-$(CONFIG_KGDB) += gdb_hook.o
+16 -7
arch/mips/philips/pnx8550/common/int.c
··· 38 38 #include <int.h> 39 39 #include <uart.h> 40 40 41 - extern asmlinkage void cp0_irqdispatch(void); 42 - 43 41 static DEFINE_SPINLOCK(irq_lock); 44 42 45 43 /* default prio for interrupts */ ··· 53 55 1 // 70 54 56 }; 55 57 56 - void hw0_irqdispatch(int irq, struct pt_regs *regs) 58 + static void hw0_irqdispatch(int irq, struct pt_regs *regs) 57 59 { 58 60 /* find out which interrupt */ 59 61 irq = PNX8550_GIC_VECTOR_0 >> 3; ··· 66 68 } 67 69 68 70 69 - void timer_irqdispatch(int irq, struct pt_regs *regs) 71 + static void timer_irqdispatch(int irq, struct pt_regs *regs) 70 72 { 71 73 irq = (0x01c0 & read_c0_config7()) >> 6; 72 74 ··· 84 86 if (irq & 0x4) { 85 87 do_IRQ(PNX8550_INT_TIMER3, regs); 86 88 } 89 + } 90 + 91 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 92 + { 93 + unsigned int pending = read_c0_status() & read_c0_cause(); 94 + 95 + if (pending & STATUSF_IP2) 96 + do_IRQ(2, regs); 97 + else if (pending & STATUSF_IP7) { 98 + if (read_c0_config7() & 0x01c0) 99 + timer_irqdispatch(7, regs); 100 + } 101 + 102 + spurious_interrupt(regs); 87 103 } 88 104 89 105 static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) ··· 234 222 { 235 223 int i; 236 224 int configPR; 237 - 238 - /* init of cp0 interrupts */ 239 - set_except_vector(0, cp0_irqdispatch); 240 225 241 226 for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { 242 227 irq_desc[i].handler = &level_irq_type;
-77
arch/mips/philips/pnx8550/common/mipsIRQ.S
··· 1 - /* 2 - * Copyright (c) 2002 Philips, Inc. All rights. 3 - * Copyright (c) 2002 Red Hat, Inc. All rights. 4 - * 5 - * This software may be freely redistributed under the terms of the 6 - * GNU General Public License. 7 - * 8 - * You should have received a copy of the GNU General Public License 9 - * along with this program; if not, write to the Free Software 10 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 11 - * 12 - * Based upon arch/mips/galileo-boards/ev64240/int-handler.S 13 - * 14 - */ 15 - #include <asm/asm.h> 16 - #include <asm/mipsregs.h> 17 - #include <asm/addrspace.h> 18 - #include <asm/regdef.h> 19 - #include <asm/stackframe.h> 20 - 21 - /* 22 - * cp0_irqdispatch 23 - * 24 - * Code to handle in-core interrupt exception. 25 - */ 26 - 27 - .align 5 28 - .set reorder 29 - .set noat 30 - NESTED(cp0_irqdispatch, PT_SIZE, sp) 31 - SAVE_ALL 32 - CLI 33 - .set at 34 - mfc0 t0,CP0_CAUSE 35 - mfc0 t2,CP0_STATUS 36 - 37 - and t0,t2 38 - 39 - andi t1,t0,STATUSF_IP2 /* int0 hardware line */ 40 - bnez t1,ll_hw0_irq 41 - nop 42 - 43 - andi t1,t0,STATUSF_IP7 /* int5 hardware line */ 44 - bnez t1,ll_timer_irq 45 - nop 46 - 47 - /* wrong alarm or masked ... */ 48 - 49 - jal spurious_interrupt 50 - nop 51 - j ret_from_irq 52 - END(cp0_irqdispatch) 53 - 54 - .align 5 55 - .set reorder 56 - ll_hw0_irq: 57 - li a0,2 58 - move a1,sp 59 - jal hw0_irqdispatch 60 - nop 61 - j ret_from_irq 62 - nop 63 - 64 - .align 5 65 - .set reorder 66 - ll_timer_irq: 67 - mfc0 t3,CP0_CONFIG,7 68 - andi t4,t3,0x01c0 69 - beqz t4,ll_timer_out 70 - nop 71 - li a0,7 72 - move a1,sp 73 - jal timer_irqdispatch 74 - nop 75 - 76 - ll_timer_out: j ret_from_irq 77 - nop
+1 -1
arch/mips/pmc-sierra/yosemite/Makefile
··· 2 2 # Makefile for the PMC-Sierra Titan 3 3 # 4 4 5 - obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o 5 + obj-y += irq.o i2c-yosemite.o prom.o py-console.o setup.o 6 6 7 7 obj-$(CONFIG_KGDB) += dbg_io.o 8 8 obj-$(CONFIG_SMP) += smp.o
-93
arch/mips/pmc-sierra/yosemite/irq-handler.S
··· 1 - /* 2 - * Copyright 2003, 04 PMC-Sierra Inc. 3 - * Author: Manish Lachwani (lachwani@pmc-sierra.com 4 - * Copyright 2004 Ralf Baechle (ralf@linux-mips.org) 5 - * 6 - * First-level interrupt router for the PMC-Sierra Titan board 7 - * 8 - * This program is free software; you can redistribute it and/or modify it 9 - * under the terms of the GNU General Public License as published by the 10 - * Free Software Foundation; either version 2 of the License, or (at your 11 - * option) any later version. 12 - * 13 - * Titan supports Hypertransport or PCI but not both. Hence, one interrupt 14 - * line is shared between the PCI slot A and Hypertransport. This is the 15 - * Processor INTB #0. 16 - */ 17 - 18 - #include <linux/config.h> 19 - #include <asm/asm.h> 20 - #include <asm/mipsregs.h> 21 - #include <asm/addrspace.h> 22 - #include <asm/regdef.h> 23 - #include <asm/stackframe.h> 24 - 25 - .align 5 26 - NESTED(titan_handle_int, PT_SIZE, sp) 27 - SAVE_ALL 28 - CLI 29 - .set at 30 - .set noreorder 31 - la ra, ret_from_irq 32 - mfc0 t0, CP0_CAUSE 33 - mfc0 t2, CP0_STATUS 34 - 35 - and t0, t2 36 - 37 - andi t2, t0, STATUSF_IP7 /* INTB5 hardware line */ 38 - bnez t2, ll_timer_irq /* Timer */ 39 - andi t1, t0, STATUSF_IP2 /* INTB0 hardware line */ 40 - bnez t1, ll_pcia_irq /* 64-bit PCI */ 41 - andi t2, t0, STATUSF_IP3 /* INTB1 hardware line */ 42 - bnez t2, ll_pcib_irq /* second 64-bit PCI slot */ 43 - andi t1, t0, STATUSF_IP4 /* INTB2 hardware line */ 44 - bnez t1, ll_duart_irq /* UART */ 45 - andi t2, t0, STATUSF_IP5 /* SMP inter-core interrupts */ 46 - bnez t2, ll_smp_irq 47 - andi t1, t0, STATUSF_IP6 48 - bnez t1, ll_ht_irq /* Hypertransport */ 49 - 50 - move a0, sp 51 - j do_extended_irq 52 - END(titan_handle_int) 53 - 54 - .set reorder 55 - .align 5 56 - 57 - ll_pcia_irq: 58 - li a0, 2 59 - move a1, sp 60 - #ifdef CONFIG_HYPERTRANSPORT 61 - j ll_ht_smp_irq_handler 62 - #else 63 - j do_IRQ 64 - #endif 65 - 66 - ll_pcib_irq: 67 - li a0, 3 68 - move a1, sp 69 - j do_IRQ 70 - 71 - ll_duart_irq: 72 - li a0, 4 73 - move a1, sp 74 - j do_IRQ 75 - 76 - ll_smp_irq: 77 - li a0, 5 78 - move a1, sp 79 - #ifdef CONFIG_SMP 80 - j titan_mailbox_irq 81 - #else 82 - j do_IRQ 83 - #endif 84 - 85 - ll_ht_irq: 86 - li a0, 6 87 - move a1, sp 88 - j ll_ht_smp_irq_handler 89 - 90 - ll_timer_irq: 91 - li a0, 7 92 - move a1, sp 93 - j do_IRQ
+31 -2
arch/mips/pmc-sierra/yosemite/irq.c
··· 2 2 * Copyright (C) 2003 PMC-Sierra Inc. 3 3 * Author: Manish Lachwani (lachwani@pmc-sierra.com) 4 4 * 5 + * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) 6 + * 5 7 * This program is free software; you can redistribute it and/or modify it 6 8 * under the terms of the GNU General Public License as published by the 7 9 * Free Software Foundation; either version 2 of the License, or (at your ··· 57 55 #define HYPERTRANSPORT_INTC 0x7a /* INTC# */ 58 56 #define HYPERTRANSPORT_INTD 0x7b /* INTD# */ 59 57 60 - extern asmlinkage void titan_handle_int(void); 61 58 extern void jaguar_mailbox_irq(struct pt_regs *); 62 59 63 60 /* ··· 126 125 127 126 } 128 127 128 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 129 + { 130 + unsigned int cause = read_c0_cause(); 131 + unsigned int status = read_c0_status(); 132 + unsigned int pending = cause & status; 133 + 134 + if (pending & STATUSF_IP7) { 135 + do_IRQ(7, regs); 136 + } else if (pending & STATUSF_IP2) { 137 + #ifdef CONFIG_HYPERTRANSPORT 138 + ll_ht_smp_irq_handler(2, regs); 139 + #else 140 + do_IRQ(2, regs); 141 + #endif 142 + } else if (pending & STATUSF_IP3) { 143 + do_IRQ(3, regs); 144 + } else if (pending & STATUSF_IP4) { 145 + do_IRQ(4, regs); 146 + } else if (pending & STATUSF_IP5) { 147 + #ifdef CONFIG_SMP 148 + titan_mailbox_irq(regs); 149 + #else 150 + do_IRQ(5, regs); 151 + #endif 152 + } else if (pending & STATUSF_IP6) { 153 + do_IRQ(4, regs); 154 + } 155 + } 156 + 129 157 #ifdef CONFIG_KGDB 130 158 extern void init_second_port(void); 131 159 #endif ··· 166 136 { 167 137 clear_c0_status(ST0_IM); 168 138 169 - set_except_vector(0, titan_handle_int); 170 139 mips_cpu_irq_init(0); 171 140 rm7k_cpu_irq_init(8); 172 141 rm9k_cpu_irq_init(12);
+1 -1
arch/mips/qemu/Makefile
··· 2 2 # Makefile for Qemu specific kernel interface routines under Linux. 3 3 # 4 4 5 - obj-y = q-firmware.o q-int.o q-irq.o q-mem.o q-setup.o 5 + obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o 6 6 7 7 obj-$(CONFIG_SMP) += q-smp.o
-17
arch/mips/qemu/q-int.S
··· 1 - /* 2 - * Qemu interrupt handler code. 3 - * 4 - * Copyright (C) 2005 by Ralf Baechle 5 - */ 6 - #include <asm/asm.h> 7 - #include <asm/regdef.h> 8 - #include <asm/stackframe.h> 9 - 10 - .align 5 11 - NESTED(qemu_handle_int, PT_SIZE, sp) 12 - SAVE_ALL 13 - CLI 14 - move a0, sp 15 - PTR_LA ra, ret_from_irq 16 - j do_qemu_int 17 - END(qemu_handle_int)
+1 -2
arch/mips/qemu/q-irq.c
··· 9 9 10 10 extern asmlinkage void qemu_handle_int(void); 11 11 12 - asmlinkage void do_qemu_int(struct pt_regs *regs) 12 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 13 13 { 14 14 unsigned int pending = read_c0_status() & read_c0_cause(); 15 15 ··· 29 29 30 30 void __init arch_init_irq(void) 31 31 { 32 - set_except_vector(0, qemu_handle_int); 33 32 mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */ 34 33 35 34 init_i8259_irqs();
+1 -1
arch/mips/sgi-ip22/Makefile
··· 3 3 # under Linux. 4 4 # 5 5 6 - obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ 6 + obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ 7 7 ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o 8 8 9 9 obj-$(CONFIG_EISA) += ip22-eisa.o
+53 -6
arch/mips/sgi-ip22/ip22-int.c
··· 37 37 static char lc2msk_to_irqnr[256]; 38 38 static char lc3msk_to_irqnr[256]; 39 39 40 - extern asmlinkage void indyIRQ(void); 41 40 extern int ip22_eisa_init(void); 42 41 43 42 static void enable_local0_irq(unsigned int irq) ··· 223 224 .end = end_local3_irq, 224 225 }; 225 226 226 - void indy_local0_irqdispatch(struct pt_regs *regs) 227 + static void indy_local0_irqdispatch(struct pt_regs *regs) 227 228 { 228 229 u8 mask = sgint->istat0 & sgint->imask0; 229 230 u8 mask2; ··· 241 242 return; 242 243 } 243 244 244 - void indy_local1_irqdispatch(struct pt_regs *regs) 245 + static void indy_local1_irqdispatch(struct pt_regs *regs) 245 246 { 246 247 u8 mask = sgint->istat1 & sgint->imask1; 247 248 u8 mask2; ··· 261 262 262 263 extern void ip22_be_interrupt(int irq, struct pt_regs *regs); 263 264 264 - void indy_buserror_irq(struct pt_regs *regs) 265 + static void indy_buserror_irq(struct pt_regs *regs) 265 266 { 266 267 int irq = SGI_BUSERR_IRQ; 267 268 ··· 305 306 #else 306 307 #define SGI_INTERRUPTS SGINT_LOCAL3 307 308 #endif 309 + 310 + extern void indy_r4k_timer_interrupt(struct pt_regs *regs); 311 + extern void indy_8254timer_irq(struct pt_regs *regs); 312 + 313 + /* 314 + * IRQs on the INDY look basically (barring software IRQs which we don't use 315 + * at all) like: 316 + * 317 + * MIPS IRQ Source 318 + * -------- ------ 319 + * 0 Software (ignored) 320 + * 1 Software (ignored) 321 + * 2 Local IRQ level zero 322 + * 3 Local IRQ level one 323 + * 4 8254 Timer zero 324 + * 5 8254 Timer one 325 + * 6 Bus Error 326 + * 7 R4k timer (what we use) 327 + * 328 + * We handle the IRQ according to _our_ priority which is: 329 + * 330 + * Highest ---- R4k Timer 331 + * Local IRQ zero 332 + * Local IRQ one 333 + * Bus Error 334 + * 8254 Timer zero 335 + * Lowest ---- 8254 Timer one 336 + * 337 + * then we just return, if multiple IRQs are pending then we will just take 338 + * another exception, big deal. 339 + */ 340 + 341 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 342 + { 343 + unsigned int pending = read_c0_cause(); 344 + 345 + /* 346 + * First we check for r4k counter/timer IRQ. 347 + */ 348 + if (pending & CAUSEF_IP7) 349 + indy_r4k_timer_interrupt(regs); 350 + else if (pending & CAUSEF_IP2) 351 + indy_local0_irqdispatch(regs); 352 + else if (pending & CAUSEF_IP3) 353 + indy_local1_irqdispatch(regs); 354 + else if (pending & CAUSEF_IP6) 355 + indy_buserror_irq(regs); 356 + else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) 357 + indy_8254timer_irq(regs); 358 + } 308 359 309 360 extern void mips_cpu_irq_init(unsigned int irq_base); 310 361 ··· 417 368 sgint->imask1 = 0; 418 369 sgint->cmeimask0 = 0; 419 370 sgint->cmeimask1 = 0; 420 - 421 - set_except_vector(0, indyIRQ); 422 371 423 372 /* init CPU irqs */ 424 373 mips_cpu_irq_init(SGINT_CPU);
-118
arch/mips/sgi-ip22/ip22-irq.S
··· 1 - /* 2 - * ip22-irq.S: Interrupt exception dispatch code for FullHouse and 3 - * Guiness. 4 - * 5 - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 6 - */ 7 - 8 - #include <asm/asm.h> 9 - #include <asm/mipsregs.h> 10 - #include <asm/regdef.h> 11 - #include <asm/stackframe.h> 12 - 13 - /* A lot of complication here is taken away because: 14 - * 15 - * 1) We handle one interrupt and return, sitting in a loop and moving across 16 - * all the pending IRQ bits in the cause register is _NOT_ the answer, the 17 - * common case is one pending IRQ so optimize in that direction. 18 - * 19 - * 2) We need not check against bits in the status register IRQ mask, that 20 - * would make this routine slow as hell. 21 - * 22 - * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in 23 - * between like BSD spl() brain-damage. 24 - * 25 - * Furthermore, the IRQs on the INDY look basically (barring software IRQs 26 - * which we don't use at all) like: 27 - * 28 - * MIPS IRQ Source 29 - * -------- ------ 30 - * 0 Software (ignored) 31 - * 1 Software (ignored) 32 - * 2 Local IRQ level zero 33 - * 3 Local IRQ level one 34 - * 4 8254 Timer zero 35 - * 5 8254 Timer one 36 - * 6 Bus Error 37 - * 7 R4k timer (what we use) 38 - * 39 - * We handle the IRQ according to _our_ priority which is: 40 - * 41 - * Highest ---- R4k Timer 42 - * Local IRQ zero 43 - * Local IRQ one 44 - * Bus Error 45 - * 8254 Timer zero 46 - * Lowest ---- 8254 Timer one 47 - * 48 - * then we just return, if multiple IRQs are pending then we will just take 49 - * another exception, big deal. 50 - */ 51 - 52 - .text 53 - .set noreorder 54 - .set noat 55 - .align 5 56 - NESTED(indyIRQ, PT_SIZE, sp) 57 - SAVE_ALL 58 - CLI 59 - .set at 60 - mfc0 s0, CP0_CAUSE # get irq mask 61 - 62 - /* First we check for r4k counter/timer IRQ. */ 63 - andi a0, s0, CAUSEF_IP7 64 - beq a0, zero, 1f 65 - andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero 66 - 67 - /* Wheee, a timer interrupt. */ 68 - jal indy_r4k_timer_interrupt 69 - move a0, sp # delay slot 70 - j ret_from_irq 71 - nop # delay slot 72 - 73 - 1: 74 - beq a0, zero, 1f 75 - andi a0, s0, CAUSEF_IP3 # delay slot, check local level one 76 - 77 - /* Wheee, local level zero interrupt. */ 78 - jal indy_local0_irqdispatch 79 - move a0, sp # delay slot 80 - 81 - j ret_from_irq 82 - nop # delay slot 83 - 84 - 1: 85 - beq a0, zero, 1f 86 - andi a0, s0, CAUSEF_IP6 # delay slot, check bus error 87 - 88 - /* Wheee, local level one interrupt. */ 89 - jal indy_local1_irqdispatch 90 - move a0, sp # delay slot 91 - j ret_from_irq 92 - nop # delay slot 93 - 94 - 1: 95 - beq a0, zero, 1f 96 - andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) # delay slot 97 - 98 - /* Wheee, an asynchronous bus error... */ 99 - jal indy_buserror_irq 100 - move a0, sp # delay slot 101 - j ret_from_irq 102 - nop # delay slot 103 - 104 - 1: 105 - /* Here by mistake? It is possible, that by the time we take 106 - * the exception the IRQ pin goes low, so just leave if this 107 - * is the case. 108 - */ 109 - beq a0, zero, 1f 110 - nop # delay slot 111 - 112 - /* Must be one of the 8254 timers... */ 113 - jal indy_8254timer_irq 114 - move a0, sp # delay slot 115 - 1: 116 - j ret_from_irq 117 - nop # delay slot 118 - END(indyIRQ)
+1 -1
arch/mips/sgi-ip27/Makefile
··· 2 2 # Makefile for the IP27 specific kernel interface routines under Linux. 3 3 # 4 4 5 - obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \ 5 + obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o \ 6 6 ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \ 7 7 ip27-timer.o ip27-hubio.o ip27-xtalk.o 8 8
-4
arch/mips/sgi-ip27/TODO
··· 9 9 in irix? 10 10 6. Investigate why things do not work without the setup_test() call 11 11 being invoked on all nodes in ip27-memory.c. 12 - 7. Too many CLIs in the locore handlers : 13 - For the low level handlers set up by set_except_vector(), 14 - __tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror, 15 - investigate whether the code should do CLI, STI or KMODE. 16 12 8. Too many do_page_faults invoked - investigate. 17 13 9. start_thread must turn off UX64 ... and define tlb_refill_debug. 18 14 10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
-45
arch/mips/sgi-ip27/ip27-irq-glue.S
··· 1 - /* 2 - * This file is subject to the terms and conditions of the GNU General Public 3 - * License. See the file "COPYING" in the main directory of this archive 4 - * for more details. 5 - * 6 - * Copyright (C) 1999 Ralf Baechle 7 - * Copyright (C) 1999 Silicon Graphics, Inc. 8 - */ 9 - #include <asm/asm.h> 10 - #include <asm/mipsregs.h> 11 - #include <asm/regdef.h> 12 - #include <asm/stackframe.h> 13 - 14 - .text 15 - .align 5 16 - NESTED(ip27_irq, PT_SIZE, sp) 17 - SAVE_ALL 18 - CLI 19 - 20 - mfc0 s0, CP0_CAUSE 21 - mfc0 t0, CP0_STATUS 22 - and s0, t0 23 - move a0, sp 24 - PTR_LA ra, ret_from_irq 25 - 26 - /* First check for RT interrupt. */ 27 - andi t0, s0, CAUSEF_IP4 28 - bnez t0, ip4 29 - andi t0, s0, CAUSEF_IP2 30 - bnez t0, ip2 31 - andi t0, s0, CAUSEF_IP3 32 - bnez t0, ip3 33 - andi t0, s0, CAUSEF_IP5 34 - bnez t0, ip5 35 - andi t0, s0, CAUSEF_IP6 36 - bnez t0, ip6 37 - j ra 38 - 39 - ip2: j ip27_do_irq_mask0 # PI_INT_PEND_0 or CC_PEND_{A|B} 40 - ip3: j ip27_do_irq_mask1 # PI_INT_PEND_1 41 - ip4: j ip27_rt_timer_interrupt 42 - ip5: j ip27_prof_timer 43 - ip6: j ip27_hub_error 44 - 45 - END(ip27_irq)
+22 -5
arch/mips/sgi-ip27/ip27-irq.c
··· 130 130 * Kanoj 05.13.00 131 131 */ 132 132 133 - void ip27_do_irq_mask0(struct pt_regs *regs) 133 + static void ip27_do_irq_mask0(struct pt_regs *regs) 134 134 { 135 135 int irq, swlevel; 136 136 hubreg_t pend0, mask0; ··· 171 171 LOCAL_HUB_L(PI_INT_PEND0); 172 172 } 173 173 174 - void ip27_do_irq_mask1(struct pt_regs *regs) 174 + static void ip27_do_irq_mask1(struct pt_regs *regs) 175 175 { 176 176 int irq, swlevel; 177 177 hubreg_t pend1, mask1; ··· 196 196 LOCAL_HUB_L(PI_INT_PEND1); 197 197 } 198 198 199 - void ip27_prof_timer(struct pt_regs *regs) 199 + static void ip27_prof_timer(struct pt_regs *regs) 200 200 { 201 201 panic("CPU %d got a profiling interrupt", smp_processor_id()); 202 202 } 203 203 204 - void ip27_hub_error(struct pt_regs *regs) 204 + static void ip27_hub_error(struct pt_regs *regs) 205 205 { 206 206 panic("CPU %d got a hub error interrupt", smp_processor_id()); 207 207 } ··· 421 421 return irq; 422 422 } 423 423 424 + extern void ip27_rt_timer_interrupt(struct pt_regs *regs); 425 + 426 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 427 + { 428 + unsigned long pending = read_c0_cause() & read_c0_status(); 429 + 430 + if (pending & CAUSEF_IP4) 431 + ip27_rt_timer_interrupt(regs); 432 + else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */ 433 + ip27_do_irq_mask0(regs); 434 + else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */ 435 + ip27_do_irq_mask1(regs); 436 + else if (pending & CAUSEF_IP5) 437 + ip27_prof_timer(regs); 438 + else if (pending & CAUSEF_IP6) 439 + ip27_hub_error(regs); 440 + } 441 + 424 442 void __init arch_init_irq(void) 425 443 { 426 - set_except_vector(0, ip27_irq); 427 444 } 428 445 429 446 void install_ipi(void)
+1 -1
arch/mips/sgi-ip32/Makefile
··· 3 3 # under Linux. 4 4 # 5 5 6 - obj-y += ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \ 6 + obj-y += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \ 7 7 crime.o ip32-memory.o 8 8 9 9 EXTRA_AFLAGS := $(CFLAGS)
-86
arch/mips/sgi-ip32/ip32-irq-glue.S
··· 1 - /* 2 - * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead 3 - * 4 - * This file is subject to the terms and conditions of the GNU General Public 5 - * License. See the file "COPYING" in the main directory of this archive 6 - * for more details. 7 - * 8 - * Copyright (C) 2000 Harald Koerfgen 9 - * Copyright (C) 2001 Keith M Wesolowski 10 - */ 11 - #include <asm/asm.h> 12 - #include <asm/regdef.h> 13 - #include <asm/mipsregs.h> 14 - #include <asm/stackframe.h> 15 - #include <asm/addrspace.h> 16 - 17 - .text 18 - .set noreorder 19 - .set noat 20 - .align 5 21 - NESTED(ip32_handle_int, PT_SIZE, ra) 22 - .set noat 23 - SAVE_ALL 24 - CLI # TEST: interrupts should be off 25 - .set at 26 - .set noreorder 27 - 28 - mfc0 s0,CP0_CAUSE 29 - 30 - andi t1, s0, IE_IRQ0 31 - bnez t1, handle_irq0 32 - andi t1, s0, IE_IRQ1 33 - bnez t1, handle_irq1 34 - andi t1, s0, IE_IRQ2 35 - bnez t1, handle_irq2 36 - andi t1, s0, IE_IRQ3 37 - bnez t1, handle_irq3 38 - andi t1, s0, IE_IRQ4 39 - bnez t1, handle_irq4 40 - andi t1, s0, IE_IRQ5 41 - bnez t1, handle_irq5 42 - nop 43 - 44 - /* Either someone has triggered the "software interrupts" 45 - * or we lost an interrupt somehow. Ignore it. 46 - */ 47 - j ret_from_irq 48 - nop 49 - 50 - handle_irq0: 51 - jal ip32_irq0 52 - move a0, sp 53 - j ret_from_irq 54 - nop 55 - 56 - handle_irq1: 57 - jal ip32_irq1 58 - move a0, sp 59 - j ret_from_irq 60 - nop 61 - 62 - handle_irq2: 63 - jal ip32_irq2 64 - move a0, sp 65 - j ret_from_irq 66 - nop 67 - 68 - handle_irq3: 69 - jal ip32_irq3 70 - move a0, sp 71 - j ret_from_irq 72 - nop 73 - 74 - handle_irq4: 75 - jal ip32_irq4 76 - move a0, sp 77 - j ret_from_irq 78 - nop 79 - 80 - handle_irq5: 81 - jal ip32_irq5 82 - move a0, sp 83 - j ret_from_irq 84 - nop 85 - 86 - END(ip32_handle_int)
+24 -9
arch/mips/sgi-ip32/ip32-irq.c
··· 130 130 struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, 131 131 CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; 132 132 133 - extern void ip32_handle_int(void); 134 - 135 133 /* 136 134 * For interrupts wired from a single device to the CPU. Only the clock 137 135 * uses this it seems, which is IRQ 0 and IP7. ··· 501 503 502 504 /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ 503 505 /* change this to loop over all edge-triggered irqs, exception masked out ones */ 504 - void ip32_irq0(struct pt_regs *regs) 506 + static void ip32_irq0(struct pt_regs *regs) 505 507 { 506 508 uint64_t crime_int; 507 509 int irq = 0; ··· 518 520 do_IRQ(irq, regs); 519 521 } 520 522 521 - void ip32_irq1(struct pt_regs *regs) 523 + static void ip32_irq1(struct pt_regs *regs) 522 524 { 523 525 ip32_unknown_interrupt(regs); 524 526 } 525 527 526 - void ip32_irq2(struct pt_regs *regs) 528 + static void ip32_irq2(struct pt_regs *regs) 527 529 { 528 530 ip32_unknown_interrupt(regs); 529 531 } 530 532 531 - void ip32_irq3(struct pt_regs *regs) 533 + static void ip32_irq3(struct pt_regs *regs) 532 534 { 533 535 ip32_unknown_interrupt(regs); 534 536 } 535 537 536 - void ip32_irq4(struct pt_regs *regs) 538 + static void ip32_irq4(struct pt_regs *regs) 537 539 { 538 540 ip32_unknown_interrupt(regs); 539 541 } 540 542 541 - void ip32_irq5(struct pt_regs *regs) 543 + static void ip32_irq5(struct pt_regs *regs) 542 544 { 543 545 ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs); 546 + } 547 + 548 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 549 + { 550 + unsigned int pending = read_c0_cause(); 551 + 552 + if (likely(pending & IE_IRQ0)) 553 + ip32_irq0(regs); 554 + else if (unlikely(pending & IE_IRQ1)) 555 + ip32_irq1(regs); 556 + else if (unlikely(pending & IE_IRQ2)) 557 + ip32_irq2(regs); 558 + else if (unlikely(pending & IE_IRQ3)) 559 + ip32_irq3(regs); 560 + else if (unlikely(pending & IE_IRQ4)) 561 + ip32_irq4(regs); 562 + else if (likely(pending & IE_IRQ5)) 563 + ip32_irq5(regs); 544 564 } 545 565 546 566 void __init arch_init_irq(void) ··· 572 556 crime->soft_int = 0; 573 557 mace->perif.ctrl.istat = 0; 574 558 mace->perif.ctrl.imask = 0; 575 - set_except_vector(0, ip32_handle_int); 576 559 577 560 for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { 578 561 hw_irq_controller *controller;
+1 -1
arch/mips/sibyte/bcm1480/Makefile
··· 1 - obj-y := setup.o irq.o irq_handler.o time.o 1 + obj-y := setup.o irq.o time.o 2 2 3 3 obj-$(CONFIG_SMP) += smp.o 4 4
+73 -4
arch/mips/sibyte/bcm1480/irq.c
··· 187 187 #endif 188 188 189 189 190 - /* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */ 191 - extern void bcm1480_irq_handler(void); 192 - 193 190 /*****************************************************************************/ 194 191 195 192 static unsigned int startup_bcm1480_irq(unsigned int irq) ··· 419 422 #endif 420 423 /* Enable necessary IPs, disable the rest */ 421 424 change_c0_status(ST0_IM, imask); 422 - set_except_vector(0, bcm1480_irq_handler); 423 425 424 426 #ifdef CONFIG_KGDB 425 427 if (kgdb_flag) { ··· 469 473 } 470 474 471 475 #endif /* CONFIG_KGDB */ 476 + 477 + static inline int dclz(unsigned long long x) 478 + { 479 + int lz; 480 + 481 + __asm__ ( 482 + " .set push \n" 483 + " .set mips64 \n" 484 + " dclz %0, %1 \n" 485 + " .set pop \n" 486 + : "=r" (lz) 487 + : "r" (x)); 488 + 489 + return lz; 490 + } 491 + 492 + extern void bcm1480_timer_interrupt(struct pt_regs *regs); 493 + extern void bcm1480_mailbox_interrupt(struct pt_regs *regs); 494 + extern void bcm1480_kgdb_interrupt(struct pt_regs *regs); 495 + 496 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 497 + { 498 + unsigned int pending; 499 + 500 + #ifdef CONFIG_SIBYTE_BCM1480_PROF 501 + /* Set compare to count to silence count/compare timer interrupts */ 502 + write_c0_compare(read_c0_count()); 503 + #endif 504 + 505 + pending = read_c0_cause(); 506 + 507 + #ifdef CONFIG_SIBYTE_BCM1480_PROF 508 + if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */ 509 + sbprof_cpu_intr(exception_epc(regs)); 510 + #endif 511 + 512 + if (pending & CAUSEF_IP4) 513 + bcm1480_timer_interrupt(regs); 514 + 515 + #ifdef CONFIG_SMP 516 + if (pending & CAUSEF_IP3) 517 + bcm1480_mailbox_interrupt(regs); 518 + #endif 519 + 520 + #ifdef CONFIG_KGDB 521 + if (pending & CAUSEF_IP6) 522 + bcm1480_kgdb_interrupt(regs); /* KGDB (uart 1) */ 523 + #endif 524 + 525 + if (pending & CAUSEF_IP2) { 526 + unsigned long long mask_h, mask_l; 527 + unsigned long base; 528 + 529 + /* 530 + * Default...we've hit an IP[2] interrupt, which means we've 531 + * got to check the 1480 interrupt registers to figure out what 532 + * to do. Need to detect which CPU we're on, now that 533 + * smp_affinity is supported. 534 + */ 535 + base = A_BCM1480_IMR_MAPPER(smp_processor_id()); 536 + mask_h = __raw_readq( 537 + IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H)); 538 + mask_l = __raw_readq( 539 + IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L)); 540 + 541 + if (!mask_h) { 542 + if (mask_h ^ 1) 543 + do_IRQ(63 - dclz(mask_h), regs); 544 + else 545 + do_IRQ(127 - dclz(mask_l), regs); 546 + } 547 + } 548 + }
-165
arch/mips/sibyte/bcm1480/irq_handler.S
··· 1 - /* 2 - * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 2 7 - * of the License, or (at your option) any later version. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - * You should have received a copy of the GNU General Public License 15 - * along with this program; if not, write to the Free Software 16 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 - */ 18 - 19 - /* 20 - * bcm1480_irq_handler() is the routine that is actually called when an 21 - * interrupt occurs. It is installed as the exception vector handler in 22 - * init_IRQ() in arch/mips/sibyte/bcm1480/irq.c 23 - * 24 - * In the handle we figure out which interrupts need handling, and use that 25 - * to call the dispatcher, which will take care of actually calling 26 - * registered handlers 27 - * 28 - * Note that we take care of all raised interrupts in one go at the handler. 29 - * This is more BSDish than the Indy code, and also, IMHO, more sane. 30 - */ 31 - #include <linux/config.h> 32 - 33 - #include <asm/addrspace.h> 34 - #include <asm/asm.h> 35 - #include <asm/mipsregs.h> 36 - #include <asm/regdef.h> 37 - #include <asm/stackframe.h> 38 - #include <asm/sibyte/sb1250_defs.h> 39 - #include <asm/sibyte/bcm1480_regs.h> 40 - #include <asm/sibyte/bcm1480_int.h> 41 - 42 - /* 43 - * What a pain. We have to be really careful saving the upper 32 bits of any 44 - * register across function calls if we don't want them trashed--since were 45 - * running in -o32, the calling routing never saves the full 64 bits of a 46 - * register across a function call. Being the interrupt handler, we're 47 - * guaranteed that interrupts are disabled during this code so we don't have 48 - * to worry about random interrupts blasting the high 32 bits. 49 - */ 50 - 51 - .text 52 - .set push 53 - .set noreorder 54 - .set noat 55 - .set mips64 56 - #.set mips4 57 - .align 5 58 - NESTED(bcm1480_irq_handler, PT_SIZE, sp) 59 - SAVE_ALL 60 - CLI 61 - 62 - #ifdef CONFIG_SIBYTE_BCM1480_PROF 63 - /* Set compare to count to silence count/compare timer interrupts */ 64 - mfc0 t1, CP0_COUNT 65 - mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */ 66 - #endif 67 - /* Read cause */ 68 - mfc0 s0, CP0_CAUSE 69 - 70 - #ifdef CONFIG_SIBYTE_BCM1480_PROF 71 - /* Cpu performance counter interrupt is routed to IP[7] */ 72 - andi t1, s0, CAUSEF_IP7 73 - beqz t1, 0f 74 - srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */ 75 - and t1, t1, 0x4 /* mask to get just BD bit */ 76 - #ifdef CONFIG_MIPS64 77 - dmfc0 a0, CP0_EPC 78 - daddu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ 79 - #else 80 - mfc0 a0, CP0_EPC 81 - addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ 82 - #endif 83 - jal sbprof_cpu_intr 84 - nop 85 - j ret_from_irq 86 - nop 87 - 0: 88 - #endif 89 - 90 - /* Timer interrupt is routed to IP[4] */ 91 - andi t1, s0, CAUSEF_IP4 92 - beqz t1, 1f 93 - nop 94 - jal bcm1480_timer_interrupt 95 - move a0, sp /* Pass the registers along */ 96 - j ret_from_irq 97 - nop /* delay slot */ 98 - 1: 99 - 100 - #ifdef CONFIG_SMP 101 - /* Mailbox interrupt is routed to IP[3] */ 102 - andi t1, s0, CAUSEF_IP3 103 - beqz t1, 2f 104 - nop 105 - jal bcm1480_mailbox_interrupt 106 - move a0, sp 107 - j ret_from_irq 108 - nop /* delay slot */ 109 - 2: 110 - #endif 111 - 112 - #ifdef CONFIG_KGDB 113 - /* KGDB (uart 1) interrupt is routed to IP[6] */ 114 - andi t1, s0, CAUSEF_IP6 115 - beqz t1, 3f 116 - nop /* delay slot */ 117 - jal bcm1480_kgdb_interrupt 118 - move a0, sp 119 - j ret_from_irq 120 - nop /* delay slot */ 121 - 3: 122 - #endif 123 - 124 - and t1, s0, CAUSEF_IP2 125 - beqz t1, 9f 126 - nop 127 - 128 - /* 129 - * Default...we've hit an IP[2] interrupt, which means we've got 130 - * to check the 1480 interrupt registers to figure out what to do 131 - * Need to detect which CPU we're on, now that smp_affinity is 132 - * supported. 133 - */ 134 - PTR_LA v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE 135 - #ifdef CONFIG_SMP 136 - lw t1, TI_CPU($28) 137 - sll t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT 138 - addu v0, v0, t1 139 - #endif 140 - 141 - /* Read IP[2] status (get both high and low halves of status) */ 142 - ld s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0) 143 - ld s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0) 144 - 145 - move s2, zero /* intr number */ 146 - li s3, 64 147 - 148 - beqz s0, 9f /* No interrupts. Return. */ 149 - move a1, sp 150 - 151 - xori s4, s0, 1 /* if s0 (_H) == 1, it's a low intr, so... */ 152 - movz s2, s3, s4 /* start the intr number at 64, and */ 153 - movz s0, s1, s4 /* look at the low status value. */ 154 - 155 - dclz s1, s0 /* Find the next interrupt. */ 156 - dsubu a0, zero, s1 157 - daddiu a0, a0, 63 158 - jal do_IRQ 159 - daddu a0, a0, s2 160 - 161 - 9: j ret_from_irq 162 - nop 163 - 164 - .set pop 165 - END(bcm1480_irq_handler)
+1 -1
arch/mips/sibyte/sb1250/Makefile
··· 1 - obj-y := setup.o irq.o irq_handler.o time.o 1 + obj-y := setup.o irq.o time.o 2 2 3 3 obj-$(CONFIG_SMP) += smp.o 4 4 obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o
+72 -6
arch/mips/sibyte/sb1250/irq.c
··· 163 163 } 164 164 #endif 165 165 166 - 167 - /* Defined in arch/mips/sibyte/sb1250/irq_handler.S */ 168 - extern void sb1250_irq_handler(void); 169 - 170 166 /*****************************************************************************/ 171 167 172 168 static unsigned int startup_sb1250_irq(unsigned int irq) ··· 375 379 #endif 376 380 /* Enable necessary IPs, disable the rest */ 377 381 change_c0_status(ST0_IM, imask); 378 - set_except_vector(0, sb1250_irq_handler); 379 382 380 383 #ifdef CONFIG_KGDB 381 384 if (kgdb_flag) { ··· 404 409 #define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) 405 410 #define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) 406 411 407 - void sb1250_kgdb_interrupt(struct pt_regs *regs) 412 + static void sb1250_kgdb_interrupt(struct pt_regs *regs) 408 413 { 409 414 /* 410 415 * Clear break-change status (allow some time for the remote ··· 419 424 } 420 425 421 426 #endif /* CONFIG_KGDB */ 427 + 428 + static inline int dclz(unsigned long long x) 429 + { 430 + int lz; 431 + 432 + __asm__ ( 433 + " .set push \n" 434 + " .set mips64 \n" 435 + " dclz %0, %1 \n" 436 + " .set pop \n" 437 + : "=r" (lz) 438 + : "r" (x)); 439 + 440 + return lz; 441 + } 442 + 443 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 444 + { 445 + unsigned int pending; 446 + 447 + #ifdef CONFIG_SIBYTE_SB1250_PROF 448 + /* Set compare to count to silence count/compare timer interrupts */ 449 + write_c0_count(read_c0_count()); 450 + #endif 451 + 452 + /* 453 + * What a pain. We have to be really careful saving the upper 32 bits 454 + * of any * register across function calls if we don't want them 455 + * trashed--since were running in -o32, the calling routing never saves 456 + * the full 64 bits of a register across a function call. Being the 457 + * interrupt handler, we're guaranteed that interrupts are disabled 458 + * during this code so we don't have to worry about random interrupts 459 + * blasting the high 32 bits. 460 + */ 461 + 462 + pending = read_c0_cause(); 463 + 464 + #ifdef CONFIG_SIBYTE_SB1250_PROF 465 + if (pending & CAUSEF_IP7) { /* Cpu performance counter interrupt */ 466 + sbprof_cpu_intr(exception_epc(regs)); 467 + } 468 + #endif 469 + 470 + if (pending & CAUSEF_IP4) 471 + sb1250_timer_interrupt(regs); 472 + 473 + #ifdef CONFIG_SMP 474 + if (pending & CAUSEF_IP3) 475 + sb1250_mailbox_interrupt(regs); 476 + #endif 477 + 478 + #ifdef CONFIG_KGDB 479 + if (pending & CAUSEF_IP6) /* KGDB (uart 1) */ 480 + sb1250_kgdb_interrupt(regs); 481 + #endif 482 + 483 + if (pending & CAUSEF_IP2) { 484 + unsigned long long mask; 485 + 486 + /* 487 + * Default...we've hit an IP[2] interrupt, which means we've 488 + * got to check the 1250 interrupt registers to figure out what 489 + * to do. Need to detect which CPU we're on, now that 490 + ~ smp_affinity is supported. 491 + */ 492 + mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(), 493 + R_IMR_INTERRUPT_STATUS_BASE))); 494 + if (mask) 495 + do_IRQ(63 - dclz(mask), regs); 496 + } 497 + }
-147
arch/mips/sibyte/sb1250/irq_handler.S
··· 1 - /* 2 - * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 2 7 - * of the License, or (at your option) any later version. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - * You should have received a copy of the GNU General Public License 15 - * along with this program; if not, write to the Free Software 16 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 - */ 18 - 19 - /* 20 - * sb1250_handle_int() is the routine that is actually called when an interrupt 21 - * occurs. It is installed as the exception vector handler in arch_init_irq() 22 - * in arch/mips/sibyte/sb1250/irq.c 23 - * 24 - * In the handle we figure out which interrupts need handling, and use that to 25 - * call the dispatcher, which will take care of actually calling registered 26 - * handlers 27 - * 28 - * Note that we take care of all raised interrupts in one go at the handler. 29 - * This is more BSDish than the Indy code, and also, IMHO, more sane. 30 - */ 31 - #include <linux/config.h> 32 - 33 - #include <asm/addrspace.h> 34 - #include <asm/asm.h> 35 - #include <asm/mipsregs.h> 36 - #include <asm/regdef.h> 37 - #include <asm/stackframe.h> 38 - #include <asm/sibyte/sb1250_defs.h> 39 - #include <asm/sibyte/sb1250_regs.h> 40 - #include <asm/sibyte/sb1250_int.h> 41 - 42 - /* 43 - * What a pain. We have to be really careful saving the upper 32 bits of any 44 - * register across function calls if we don't want them trashed--since were 45 - * running in -o32, the calling routing never saves the full 64 bits of a 46 - * register across a function call. Being the interrupt handler, we're 47 - * guaranteed that interrupts are disabled during this code so we don't have 48 - * to worry about random interrupts blasting the high 32 bits. 49 - */ 50 - 51 - .text 52 - .set push 53 - .set noreorder 54 - .set noat 55 - .set mips64 56 - .align 5 57 - NESTED(sb1250_irq_handler, PT_SIZE, sp) 58 - SAVE_ALL 59 - CLI 60 - 61 - #ifdef CONFIG_SIBYTE_SB1250_PROF 62 - /* Set compare to count to silence count/compare timer interrupts */ 63 - mfc0 t1, CP0_COUNT 64 - mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */ 65 - #endif 66 - /* Read cause */ 67 - mfc0 s0, CP0_CAUSE 68 - 69 - #ifdef CONFIG_SIBYTE_SB1250_PROF 70 - /* Cpu performance counter interrupt is routed to IP[7] */ 71 - andi t1, s0, CAUSEF_IP7 72 - beqz t1, 0f 73 - srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */ 74 - and t1, t1, 0x4 /* mask to get just BD bit */ 75 - mfc0 a0, CP0_EPC 76 - jal sbprof_cpu_intr 77 - addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ 78 - j ret_from_irq 79 - nop 80 - 0: 81 - #endif 82 - 83 - /* Timer interrupt is routed to IP[4] */ 84 - andi t1, s0, CAUSEF_IP4 85 - beqz t1, 1f 86 - nop 87 - jal sb1250_timer_interrupt 88 - move a0, sp /* Pass the registers along */ 89 - j ret_from_irq 90 - nop # delay slot 91 - 1: 92 - 93 - #ifdef CONFIG_SMP 94 - /* Mailbox interrupt is routed to IP[3] */ 95 - andi t1, s0, CAUSEF_IP3 96 - beqz t1, 2f 97 - nop 98 - jal sb1250_mailbox_interrupt 99 - move a0, sp 100 - j ret_from_irq 101 - nop # delay slot 102 - 2: 103 - #endif 104 - 105 - #ifdef CONFIG_KGDB 106 - /* KGDB (uart 1) interrupt is routed to IP[6] */ 107 - andi t1, s0, CAUSEF_IP6 108 - beqz t1, 1f 109 - nop # delay slot 110 - jal sb1250_kgdb_interrupt 111 - move a0, sp 112 - j ret_from_irq 113 - nop # delay slot 114 - 1: 115 - #endif 116 - 117 - and t1, s0, CAUSEF_IP2 118 - beqz t1, 4f 119 - nop 120 - 121 - /* 122 - * Default...we've hit an IP[2] interrupt, which means we've got to 123 - * check the 1250 interrupt registers to figure out what to do 124 - * Need to detect which CPU we're on, now that smp_affinity is supported. 125 - */ 126 - PTR_LA v0, CKSEG1 + A_IMR_CPU0_BASE 127 - #ifdef CONFIG_SMP 128 - lw t1, TI_CPU($28) 129 - sll t1, IMR_REGISTER_SPACING_SHIFT 130 - addu v0, t1 131 - #endif 132 - ld s0, R_IMR_INTERRUPT_STATUS_BASE(v0) /* read IP[2] status */ 133 - 134 - beqz s0, 4f /* No interrupts. Return */ 135 - move a1, sp 136 - 137 - 3: dclz s1, s0 /* Find the next interrupt */ 138 - dsubu a0, zero, s1 139 - daddiu a0, a0, 63 140 - jal do_IRQ 141 - nop 142 - 143 - 4: j ret_from_irq 144 - nop 145 - 146 - .set pop 147 - END(sb1250_irq_handler)
+1 -1
arch/mips/sni/Makefile
··· 2 2 # Makefile for the SNI specific part of the kernel 3 3 # 4 4 5 - obj-y += int-handler.o irq.o pcimt_scache.o reset.o setup.o 5 + obj-y += irq.o pcimt_scache.o reset.o setup.o 6 6 7 7 EXTRA_AFLAGS := $(CFLAGS)
-106
arch/mips/sni/int-handler.S
··· 1 - /* 2 - * SNI RM200 PCI specific interrupt handler code. 3 - * 4 - * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle 5 - */ 6 - #include <asm/asm.h> 7 - #include <asm/mipsregs.h> 8 - #include <asm/regdef.h> 9 - #include <asm/sni.h> 10 - #include <asm/stackframe.h> 11 - 12 - /* 13 - * The PCI ASIC has the nasty property that it may delay writes if it is busy. 14 - * As a consequence from writes that have not graduated when we exit from the 15 - * interrupt handler we might catch a spurious interrupt. To avoid this we 16 - * force the PCI ASIC to graduate all writes by executing a read from the 17 - * PCI bus. 18 - */ 19 - .set noreorder 20 - .set noat 21 - .align 5 22 - NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp) 23 - SAVE_ALL 24 - CLI 25 - .set at 26 - 27 - /* Blinken light ... */ 28 - lb t0, led_cache 29 - addiu t0, 1 30 - sb t0, led_cache 31 - sb t0, PCIMT_CSLED # write only register 32 - .data 33 - led_cache: .byte 0 34 - .text 35 - 36 - mfc0 t0, CP0_STATUS 37 - mfc0 t1, CP0_CAUSE 38 - and t0, t1 39 - 40 - andi t1, t0, 0x0800 # hardware interrupt 1 41 - bnez t1, _hwint1 42 - andi t1, t0, 0x4000 # hardware interrupt 4 43 - bnez t1, _hwint4 44 - andi t1, t0, 0x2000 # hardware interrupt 3 45 - bnez t1, _hwint3 46 - andi t1, t0, 0x1000 # hardware interrupt 2 47 - bnez t1, _hwint2 48 - andi t1, t0, 0x8000 # hardware interrupt 5 49 - bnez t1, _hwint5 50 - andi t1, t0, 0x0400 # hardware interrupt 0 51 - bnez t1, _hwint0 52 - nop 53 - 54 - j restore_all # spurious interrupt 55 - nop 56 - 57 - ############################################################################## 58 - 59 - /* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug 60 - button interrupts. */ 61 - _hwint0: jal pciasic_hwint0 62 - move a0, sp 63 - j ret_from_irq 64 - nop 65 - 66 - /* 67 - * hwint 1 deals with EISA and SCSI interrupts 68 - */ 69 - _hwint1: jal pciasic_hwint1 70 - move a0, sp 71 - j ret_from_irq 72 - nop 73 - 74 - 75 - /* 76 - * This interrupt was used for the com1 console on the first prototypes; 77 - * it's unsed otherwise 78 - */ 79 - _hwint2: jal pciasic_hwint2 80 - move a0, sp 81 - j ret_from_irq 82 - nop 83 - 84 - /* 85 - * hwint 3 are the PCI interrupts A - D 86 - */ 87 - _hwint3: jal pciasic_hwint3 88 - move a0, sp 89 - j ret_from_irq 90 - nop 91 - 92 - /* 93 - * hwint 4 is used for only the onboard PCnet 32. 94 - */ 95 - _hwint4: jal pciasic_hwint4 96 - move a0, sp 97 - j ret_from_irq 98 - nop 99 - 100 - /* hwint5 is the r4k count / compare interrupt */ 101 - _hwint5: jal pciasic_hwint5 102 - move a0, sp 103 - j ret_from_irq 104 - nop 105 - 106 - END(sni_rm200_pci_handle_int)
+27 -10
arch/mips/sni/irq.c
··· 19 19 20 20 DEFINE_SPINLOCK(pciasic_lock); 21 21 22 - extern asmlinkage void sni_rm200_pci_handle_int(void); 23 - 24 22 static void enable_pciasic_irq(unsigned int irq) 25 23 { 26 24 unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); ··· 69 71 * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug 70 72 * button interrupts. Later ... 71 73 */ 72 - void pciasic_hwint0(struct pt_regs *regs) 74 + static void pciasic_hwint0(struct pt_regs *regs) 73 75 { 74 76 panic("Received int0 but no handler yet ..."); 75 77 } 76 78 77 79 /* This interrupt was used for the com1 console on the first prototypes. */ 78 - void pciasic_hwint2(struct pt_regs *regs) 80 + static void pciasic_hwint2(struct pt_regs *regs) 79 81 { 80 82 /* I think this shouldn't happen on production machines. */ 81 83 panic("hwint2 and no handler yet"); 82 84 } 83 85 84 86 /* hwint5 is the r4k count / compare interrupt */ 85 - void pciasic_hwint5(struct pt_regs *regs) 87 + static void pciasic_hwint5(struct pt_regs *regs) 86 88 { 87 89 panic("hwint5 and no handler yet"); 88 90 } ··· 103 105 * 104 106 * The EISA_INT bit in CSITPEND is high active, all others are low active. 105 107 */ 106 - void pciasic_hwint1(struct pt_regs *regs) 108 + static void pciasic_hwint1(struct pt_regs *regs) 107 109 { 108 110 u8 pend = *(volatile char *)PCIMT_CSITPEND; 109 111 unsigned long flags; ··· 133 135 /* 134 136 * hwint 3 should deal with the PCI A - D interrupts, 135 137 */ 136 - void pciasic_hwint3(struct pt_regs *regs) 138 + static void pciasic_hwint3(struct pt_regs *regs) 137 139 { 138 140 u8 pend = *(volatile char *)PCIMT_CSITPEND; 139 141 int irq; ··· 148 150 /* 149 151 * hwint 4 is used for only the onboard PCnet 32. 150 152 */ 151 - void pciasic_hwint4(struct pt_regs *regs) 153 + static void pciasic_hwint4(struct pt_regs *regs) 152 154 { 153 155 clear_c0_status(IE_IRQ4); 154 156 do_IRQ(PCIMT_IRQ_ETHERNET, regs); 155 157 set_c0_status(IE_IRQ4); 158 + } 159 + 160 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 161 + { 162 + unsigned int pending = read_c0_status() & read_c0_cause(); 163 + static unsigned char led_cache; 164 + 165 + *(volatile unsigned char *) PCIMT_CSLED = ++led_cache; 166 + 167 + if (pending & 0x0800) 168 + pciasic_hwint1(regs); 169 + else if (pending & 0x4000) 170 + pciasic_hwint4(regs); 171 + else if (pending & 0x2000) 172 + pciasic_hwint3(regs); 173 + else if (pending & 0x1000) 174 + pciasic_hwint2(regs); 175 + else if (pending & 0x8000) 176 + pciasic_hwint5(regs); 177 + else if (pending & 0x0400) 178 + pciasic_hwint0(regs); 156 179 } 157 180 158 181 void __init init_pciasic(void) ··· 194 175 void __init arch_init_irq(void) 195 176 { 196 177 int i; 197 - 198 - set_except_vector(0, sni_rm200_pci_handle_int); 199 178 200 179 init_i8259_irqs(); /* Integrated i8259 */ 201 180 init_pciasic();
+1 -1
arch/mips/tx4927/common/Makefile
··· 6 6 # unless it's something special (ie not a .c file). 7 7 # 8 8 9 - obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o tx4927_irq_handler.o 9 + obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o 10 10 11 11 obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o 12 12 obj-$(CONFIG_KGDB) += tx4927_dbgio.o
+23 -7
arch/mips/tx4927/common/tx4927_irq.c
··· 525 525 */ 526 526 void __init tx4927_irq_init(void) 527 527 { 528 - extern asmlinkage void tx4927_irq_handler(void); 529 - 530 528 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); 531 529 532 530 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); ··· 533 535 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); 534 536 tx4927_irq_pic_init(); 535 537 536 - TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, 537 - "=Calling set_except_vector(tx4927_irq_handler)\n"); 538 - set_except_vector(0, tx4927_irq_handler); 539 - 540 538 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); 541 539 542 540 return; 543 541 } 544 542 545 - int tx4927_irq_nested(void) 543 + static int tx4927_irq_nested(void) 546 544 { 547 545 int sw_irq = 0; 548 546 u32 level2; ··· 575 581 TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "+\n"); 576 582 577 583 return (sw_irq); 584 + } 585 + 586 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 587 + { 588 + unsigned int pending = read_c0_status() & read_c0_cause(); 589 + 590 + if (pending & STATUSF_IP7) /* cpu timer */ 591 + do_IRQ(TX4927_IRQ_CPU_TIMER, regs); 592 + else if (pending & STATUSF_IP2) { /* tx4927 pic */ 593 + unsigned int irq = tx4927_irq_nested(); 594 + 595 + if (unlikely(irq == 0)) { 596 + spurious_interrupt(regs); 597 + return; 598 + } 599 + do_IRQ(irq, regs); 600 + } else if (pending & STATUSF_IP0) /* user line 0 */ 601 + do_IRQ(TX4927_IRQ_USER0, regs); 602 + else if (pending & STATUSF_IP1) /* user line 1 */ 603 + do_IRQ(TX4927_IRQ_USER1, regs); 604 + else 605 + spurious_interrupt(regs); 578 606 }
-104
arch/mips/tx4927/common/tx4927_irq_handler.S
··· 1 - /* 2 - * linux/arch/mips/tx4927/common/tx4927_irq_handler.S 3 - * 4 - * Primary interrupt handler for tx4927 based systems 5 - * 6 - * Author: MontaVista Software, Inc. 7 - * Author: jsun@mvista.com or jsun@junsun.net 8 - * source@mvista.com 9 - * 10 - * Copyright 2001-2002 MontaVista Software Inc. 11 - * 12 - * This program is free software; you can redistribute it and/or modify it 13 - * under the terms of the GNU General Public License as published by the 14 - * Free Software Foundation; either version 2 of the License, or (at your 15 - * option) any later version. 16 - * 17 - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 23 - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 26 - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 - * 28 - * You should have received a copy of the GNU General Public License along 29 - * with this program; if not, write to the Free Software Foundation, Inc., 30 - * 675 Mass Ave, Cambridge, MA 02139, USA. 31 - */ 32 - #include <asm/asm.h> 33 - #include <asm/mipsregs.h> 34 - #include <asm/addrspace.h> 35 - #include <asm/regdef.h> 36 - #include <asm/stackframe.h> 37 - #include <asm/tx4927/tx4927.h> 38 - 39 - .align 5 40 - NESTED(tx4927_irq_handler, PT_SIZE, sp) 41 - SAVE_ALL 42 - CLI 43 - .set at 44 - 45 - mfc0 t0, CP0_CAUSE 46 - mfc0 t1, CP0_STATUS 47 - and t0, t1 48 - 49 - andi t1, t0, STATUSF_IP7 /* cpu timer */ 50 - bnez t1, ll_ip7 51 - 52 - /* IP6..IP3 multiplexed -- do not use */ 53 - 54 - andi t1, t0, STATUSF_IP2 /* tx4927 pic */ 55 - bnez t1, ll_ip2 56 - 57 - andi t1, t0, STATUSF_IP0 /* user line 0 */ 58 - bnez t1, ll_ip0 59 - 60 - andi t1, t0, STATUSF_IP1 /* user line 1 */ 61 - bnez t1, ll_ip1 62 - 63 - .set reorder 64 - 65 - /* wrong alarm or masked ... */ 66 - jal spurious_interrupt 67 - nop 68 - j ret_from_irq 69 - END(tx4927_irq_handler) 70 - 71 - .align 5 72 - 73 - 74 - ll_ip7: 75 - li a0, TX4927_IRQ_CPU_TIMER 76 - move a1, sp 77 - jal do_IRQ 78 - j ret_from_irq 79 - 80 - ll_ip2: 81 - jal tx4927_irq_nested 82 - nop 83 - beqz v0, goto_spurious_interrupt 84 - nop 85 - move a0, v0 86 - move a1, sp 87 - jal do_IRQ 88 - j ret_from_irq 89 - 90 - goto_spurious_interrupt: 91 - j spurious_interrupt 92 - nop 93 - 94 - ll_ip1: 95 - li a0, TX4927_IRQ_USER1 96 - move a1, sp 97 - jal do_IRQ 98 - j ret_from_irq 99 - 100 - ll_ip0: 101 - li a0, TX4927_IRQ_USER0 102 - move a1, sp 103 - jal do_IRQ 104 - j ret_from_irq
+1 -1
arch/mips/tx4938/common/Makefile
··· 6 6 # unless it's something special (ie not a .c file). 7 7 # 8 8 9 - obj-y += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o 9 + obj-y += prom.o setup.o irq.o rtc_rx5c348.o 10 10 obj-$(CONFIG_KGDB) += dbgio.o 11 11
+18 -3
arch/mips/tx4938/common/irq.c
··· 392 392 void __init 393 393 tx4938_irq_init(void) 394 394 { 395 - extern asmlinkage void tx4938_irq_handler(void); 396 - 397 395 tx4938_irq_cp0_init(); 398 396 tx4938_irq_pic_init(); 399 - set_except_vector(0, tx4938_irq_handler); 400 397 401 398 return; 402 399 } ··· 418 421 419 422 wbflush(); 420 423 return (sw_irq); 424 + } 425 + 426 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 427 + { 428 + unsigned int pending = read_c0_cause() & read_c0_status(); 429 + 430 + if (pending & STATUSF_IP7) 431 + do_IRQ(TX4938_IRQ_CPU_TIMER, regs); 432 + else if (pending & STATUSF_IP2) { 433 + int irq = tx4938_irq_nested(); 434 + if (irq) 435 + do_IRQ(irq, regs); 436 + else 437 + spurious_interrupt(regs); 438 + } else if (pending & STATUSF_IP1) 439 + do_IRQ(TX4938_IRQ_USER1, regs); 440 + else if (pending & STATUSF_IP0) 441 + do_IRQ(TX4938_IRQ_USER0, regs); 421 442 }
-84
arch/mips/tx4938/common/irq_handler.S
··· 1 - /* 2 - * linux/arch/mips/tx4938/common/handler.S 3 - * 4 - * Primary interrupt handler for tx4938 based systems 5 - * Copyright (C) 2000-2001 Toshiba Corporation 6 - * 7 - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the 8 - * terms of the GNU General Public License version 2. This program is 9 - * licensed "as is" without any warranty of any kind, whether express 10 - * or implied. 11 - * 12 - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) 13 - */ 14 - #include <asm/asm.h> 15 - #include <asm/mipsregs.h> 16 - #include <asm/addrspace.h> 17 - #include <asm/regdef.h> 18 - #include <asm/stackframe.h> 19 - #include <asm/tx4938/rbtx4938.h> 20 - 21 - 22 - .align 5 23 - NESTED(tx4938_irq_handler, PT_SIZE, sp) 24 - SAVE_ALL 25 - CLI 26 - .set at 27 - 28 - mfc0 t0, CP0_CAUSE 29 - mfc0 t1, CP0_STATUS 30 - and t0, t1 31 - 32 - andi t1, t0, STATUSF_IP7 /* cpu timer */ 33 - bnez t1, ll_ip7 34 - 35 - /* IP6..IP3 multiplexed -- do not use */ 36 - 37 - andi t1, t0, STATUSF_IP2 /* tx4938 pic */ 38 - bnez t1, ll_ip2 39 - 40 - andi t1, t0, STATUSF_IP1 /* user line 1 */ 41 - bnez t1, ll_ip1 42 - 43 - andi t1, t0, STATUSF_IP0 /* user line 0 */ 44 - bnez t1, ll_ip0 45 - 46 - .set reorder 47 - 48 - nop 49 - END(tx4938_irq_handler) 50 - 51 - .align 5 52 - 53 - 54 - ll_ip7: 55 - li a0, TX4938_IRQ_CPU_TIMER 56 - move a1, sp 57 - jal do_IRQ 58 - j ret_from_irq 59 - 60 - 61 - ll_ip2: 62 - jal tx4938_irq_nested 63 - nop 64 - beqz v0, goto_spurious_interrupt 65 - nop 66 - move a0, v0 67 - move a1, sp 68 - jal do_IRQ 69 - j ret_from_irq 70 - 71 - goto_spurious_interrupt: 72 - j ret_from_irq 73 - 74 - ll_ip1: 75 - li a0, TX4938_IRQ_USER1 76 - move a1, sp 77 - jal do_IRQ 78 - j ret_from_irq 79 - 80 - ll_ip0: 81 - li a0, TX4938_IRQ_USER0 82 - move a1, sp 83 - jal do_IRQ 84 - j ret_from_irq
+1 -1
arch/mips/vr41xx/common/Makefile
··· 2 2 # Makefile for common code of the NEC VR4100 series. 3 3 # 4 4 5 - obj-y += bcu.o cmu.o icu.o init.o int-handler.o irq.o pmu.o type.o 5 + obj-y += bcu.o cmu.o icu.o init.o irq.o pmu.o type.o 6 6 obj-$(CONFIG_VRC4173) += vrc4173.o 7 7 8 8 EXTRA_AFLAGS := $(CFLAGS)
-116
arch/mips/vr41xx/common/int-handler.S
··· 1 - /* 2 - * FILE NAME 3 - * arch/mips/vr41xx/common/int-handler.S 4 - * 5 - * BRIEF MODULE DESCRIPTION 6 - * Interrupt dispatcher for the NEC VR4100 series. 7 - * 8 - * Author: Yoichi Yuasa 9 - * yyuasa@mvista.com or source@mvista.com 10 - * 11 - * Copyright 2001 MontaVista Software Inc. 12 - * 13 - * This program is free software; you can redistribute it and/or modify it 14 - * under the terms of the GNU General Public License as published by the 15 - * Free Software Foundation; either version 2 of the License, or (at your 16 - * option) any later version. 17 - * 18 - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 24 - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 27 - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 - * 29 - * You should have received a copy of the GNU General Public License along 30 - * with this program; if not, write to the Free Software Foundation, Inc., 31 - * 675 Mass Ave, Cambridge, MA 02139, USA. 32 - */ 33 - /* 34 - * Changes: 35 - * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> 36 - * - New creation, NEC VR4100 series are supported. 37 - * 38 - * Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> 39 - * - Coped with INTASSIGN of NEC VR4133. 40 - */ 41 - #include <asm/asm.h> 42 - #include <asm/regdef.h> 43 - #include <asm/mipsregs.h> 44 - #include <asm/stackframe.h> 45 - 46 - .text 47 - .set noreorder 48 - 49 - .align 5 50 - NESTED(vr41xx_handle_interrupt, PT_SIZE, ra) 51 - .set noat 52 - SAVE_ALL 53 - CLI 54 - .set at 55 - .set noreorder 56 - 57 - /* 58 - * Get the pending interrupts 59 - */ 60 - mfc0 t0, CP0_CAUSE 61 - mfc0 t1, CP0_STATUS 62 - andi t0, 0xff00 63 - and t0, t0, t1 64 - 65 - andi t1, t0, CAUSEF_IP7 # MIPS timer interrupt 66 - bnez t1, handle_irq 67 - li a0, 7 68 - 69 - andi t1, t0, 0x7800 # check for Int1-4 70 - beqz t1, 1f 71 - 72 - andi t1, t0, CAUSEF_IP3 # check for Int1 73 - bnez t1, handle_int 74 - li a0, 3 75 - 76 - andi t1, t0, CAUSEF_IP4 # check for Int2 77 - bnez t1, handle_int 78 - li a0, 4 79 - 80 - andi t1, t0, CAUSEF_IP5 # check for Int3 81 - bnez t1, handle_int 82 - li a0, 5 83 - 84 - andi t1, t0, CAUSEF_IP6 # check for Int4 85 - bnez t1, handle_int 86 - li a0, 6 87 - 88 - 1: 89 - andi t1, t0, CAUSEF_IP2 # check for Int0 90 - bnez t1, handle_int 91 - li a0, 2 92 - 93 - andi t1, t0, CAUSEF_IP0 # check for IP0 94 - bnez t1, handle_irq 95 - li a0, 0 96 - 97 - andi t1, t0, CAUSEF_IP1 # check for IP1 98 - bnez t1, handle_irq 99 - li a0, 1 100 - 101 - jal spurious_interrupt 102 - nop 103 - j ret_from_irq 104 - nop 105 - 106 - handle_int: 107 - jal irq_dispatch 108 - move a1, sp 109 - j ret_from_irq 110 - nop 111 - 112 - handle_irq: 113 - jal do_IRQ 114 - move a1, sp 115 - j ret_from_irq 116 - END(vr41xx_handle_interrupt)
+25 -4
arch/mips/vr41xx/common/irq.c
··· 59 59 60 60 EXPORT_SYMBOL_GPL(cascade_irq); 61 61 62 - asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs) 62 + static void irq_dispatch(unsigned int irq, struct pt_regs *regs) 63 63 { 64 64 irq_cascade_t *cascade; 65 65 irq_desc_t *desc; ··· 84 84 do_IRQ(irq, regs); 85 85 } 86 86 87 - extern asmlinkage void vr41xx_handle_interrupt(void); 87 + asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 88 + { 89 + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 90 + 91 + if (pending & CAUSEF_IP7) 92 + do_IRQ(7, regs); 93 + else if (pending & 0x7800) { 94 + if (pending & CAUSEF_IP3) 95 + irq_dispatch(3, regs); 96 + else if (pending & CAUSEF_IP4) 97 + irq_dispatch(4, regs); 98 + else if (pending & CAUSEF_IP5) 99 + irq_dispatch(5, regs); 100 + else if (pending & CAUSEF_IP6) 101 + irq_dispatch(6, regs); 102 + } else if (pending & CAUSEF_IP2) 103 + irq_dispatch(2, regs); 104 + else if (pending & CAUSEF_IP0) 105 + do_IRQ(0, regs); 106 + else if (pending & CAUSEF_IP1) 107 + do_IRQ(1, regs); 108 + else 109 + spurious_interrupt(regs); 110 + } 88 111 89 112 void __init arch_init_irq(void) 90 113 { 91 114 mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); 92 - 93 - set_except_vector(0, vr41xx_handle_interrupt); 94 115 }