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

[MIPS] Atlas: update interrupt handling

The following change updates the Atlas interrupt handling to match that
of Malta. Tested with a 5Kc and a 34Kf successfully.

Signed-off-by: Maciej W. Rozycki <macro@mips.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Maciej W. Rozycki and committed by
Ralf Baechle
fc095a90 3ee24e1b

+189 -71
+85 -20
arch/mips/mips-boards/atlas/atlas_int.c
··· 1 1 /* 2 - * Carsten Langgaard, carstenl@mips.com 3 - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. 2 + * Copyright (C) 1999, 2000, 2006 MIPS Technologies, Inc. 3 + * All rights reserved. 4 + * Authors: Carsten Langgaard <carstenl@mips.com> 5 + * Maciej W. Rozycki <macro@mips.com> 4 6 * 5 7 * ######################################################################## 6 8 * ··· 27 25 */ 28 26 #include <linux/compiler.h> 29 27 #include <linux/init.h> 28 + #include <linux/irq.h> 30 29 #include <linux/sched.h> 31 30 #include <linux/slab.h> 32 31 #include <linux/interrupt.h> 33 32 #include <linux/kernel_stat.h> 34 33 35 - #include <asm/irq.h> 34 + #include <asm/gdb-stub.h> 36 35 #include <asm/io.h> 36 + #include <asm/irq_cpu.h> 37 + #include <asm/msc01_ic.h> 38 + 37 39 #include <asm/mips-boards/atlas.h> 38 40 #include <asm/mips-boards/atlasint.h> 39 - #include <asm/gdb-stub.h> 40 - 41 + #include <asm/mips-boards/generic.h> 41 42 42 43 static struct atlas_ictrl_regs *atlas_hw0_icregs; 43 44 ··· 52 47 53 48 void disable_atlas_irq(unsigned int irq_nr) 54 49 { 55 - atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE)); 50 + atlas_hw0_icregs->intrsten = 1 << (irq_nr - ATLAS_INT_BASE); 56 51 iob(); 57 52 } 58 53 59 54 void enable_atlas_irq(unsigned int irq_nr) 60 55 { 61 - atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE)); 56 + atlas_hw0_icregs->intseten = 1 << (irq_nr - ATLAS_INT_BASE); 62 57 iob(); 63 58 } 64 59 ··· 112 107 if (unlikely(int_status == 0)) 113 108 return; 114 109 115 - irq = ATLASINT_BASE + ls1bit32(int_status); 110 + irq = ATLAS_INT_BASE + ls1bit32(int_status); 116 111 117 112 DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); 118 113 ··· 166 161 } 167 162 168 163 /* 169 - * IRQs on the Atlas board look basically (barring software IRQs which we 170 - * don't use at all and all external interrupt sources are combined together 171 - * on hardware interrupt 0 (MIPS IRQ 2)) like: 164 + * IRQs on the Atlas board look basically like (all external interrupt 165 + * sources are combined together on hardware interrupt 0 (MIPS IRQ 2)): 172 166 * 173 - * MIPS IRQ Source 167 + * MIPS IRQ Source 174 168 * -------- ------ 175 - * 0 Software (ignored) 176 - * 1 Software (ignored) 177 - * 2 Combined hardware interrupt (hw0) 169 + * 0 Software 0 (reschedule IPI on MT) 170 + * 1 Software 1 (remote call IPI on MT) 171 + * 2 Combined Atlas hardware interrupt (hw0) 178 172 * 3 Hardware (ignored) 179 173 * 4 Hardware (ignored) 180 174 * 5 Hardware (ignored) ··· 183 179 * We handle the IRQ according to _our_ priority which is: 184 180 * 185 181 * Highest ---- R4k Timer 186 - * Lowest ---- Combined hardware interrupt 182 + * Lowest ---- Software 0 187 183 * 188 184 * then we just return, if multiple IRQs are pending then we will just take 189 185 * another exception, big deal. ··· 197 193 198 194 if (irq == MIPSCPU_INT_ATLAS) 199 195 atlas_hw0_irqdispatch(regs); 200 - else if (irq > 0) 196 + else if (irq >= 0) 201 197 do_IRQ(MIPSCPU_INT_BASE + irq, regs); 202 198 else 203 199 spurious_interrupt(regs); 204 200 } 205 201 206 - void __init arch_init_irq(void) 202 + static inline void init_atlas_irqs (int base) 207 203 { 208 204 int i; 209 205 210 - atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *)); 206 + atlas_hw0_icregs = (struct atlas_ictrl_regs *) 207 + ioremap(ATLAS_ICTRL_REGS_BASE, 208 + sizeof(struct atlas_ictrl_regs *)); 211 209 212 210 /* 213 211 * Mask out all interrupt by writing "1" to all bit position in ··· 217 211 */ 218 212 atlas_hw0_icregs->intrsten = 0xffffffff; 219 213 220 - for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { 214 + for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) { 221 215 irq_desc[i].status = IRQ_DISABLED; 222 216 irq_desc[i].action = 0; 223 217 irq_desc[i].depth = 1; 224 218 irq_desc[i].chip = &atlas_irq_type; 225 219 spin_lock_init(&irq_desc[i].lock); 226 220 } 221 + } 222 + 223 + static struct irqaction atlasirq = { 224 + .handler = no_action, 225 + .name = "Atlas cascade" 226 + }; 227 + 228 + msc_irqmap_t __initdata msc_irqmap[] = { 229 + {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, 230 + {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, 231 + }; 232 + int __initdata msc_nr_irqs = sizeof(msc_irqmap) / sizeof(*msc_irqmap); 233 + 234 + msc_irqmap_t __initdata msc_eicirqmap[] = { 235 + {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, 236 + {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, 237 + {MSC01E_INT_ATLAS, MSC01_IRQ_LEVEL, 0}, 238 + {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, 239 + {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, 240 + {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, 241 + {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} 242 + }; 243 + int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap) / sizeof(*msc_eicirqmap); 244 + 245 + void __init arch_init_irq(void) 246 + { 247 + init_atlas_irqs(ATLAS_INT_BASE); 248 + 249 + if (!cpu_has_veic) 250 + mips_cpu_irq_init(MIPSCPU_INT_BASE); 251 + 252 + switch(mips_revision_corid) { 253 + case MIPS_REVISION_CORID_CORE_MSC: 254 + case MIPS_REVISION_CORID_CORE_FPGA2: 255 + case MIPS_REVISION_CORID_CORE_FPGA3: 256 + case MIPS_REVISION_CORID_CORE_24K: 257 + case MIPS_REVISION_CORID_CORE_EMUL_MSC: 258 + if (cpu_has_veic) 259 + init_msc_irqs (MSC01E_INT_BASE, 260 + msc_eicirqmap, msc_nr_eicirqs); 261 + else 262 + init_msc_irqs (MSC01C_INT_BASE, 263 + msc_irqmap, msc_nr_irqs); 264 + } 265 + 266 + 267 + if (cpu_has_veic) { 268 + set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch); 269 + setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq); 270 + } else if (cpu_has_vint) { 271 + set_vi_handler (MIPSCPU_INT_ATLAS, atlas_hw0_irqdispatch); 272 + #ifdef CONFIG_MIPS_MT_SMTC 273 + setup_irq_smtc (MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, 274 + &atlasirq, (0x100 << MIPSCPU_INT_ATLAS)); 275 + #else /* Not SMTC */ 276 + setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq); 277 + #endif /* CONFIG_MIPS_MT_SMTC */ 278 + } else 279 + setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq); 227 280 }
+1 -1
arch/mips/mips-boards/atlas/atlas_setup.c
··· 77 77 #else 78 78 s.iobase = ATLAS_UART_REGS_BASE+3; 79 79 #endif 80 - s.irq = ATLASINT_UART; 80 + s.irq = ATLAS_INT_UART; 81 81 s.uartclk = ATLAS_BASE_BAUD * 16; 82 82 s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; 83 83 s.iotype = UPIO_PORT;
+6 -1
arch/mips/mips-boards/generic/time.c
··· 41 41 42 42 #include <asm/mips-boards/generic.h> 43 43 #include <asm/mips-boards/prom.h> 44 + 45 + #ifdef CONFIG_MIPS_ATLAS 46 + #include <asm/mips-boards/atlasint.h> 47 + #endif 48 + #ifdef CONFIG_MIPS_MALTA 44 49 #include <asm/mips-boards/maltaint.h> 45 - #include <asm/mc146818-time.h> 50 + #endif 46 51 47 52 unsigned long cpu_khz; 48 53
+10 -10
arch/mips/pci/fixup-atlas.c
··· 21 21 22 22 #include <asm/mips-boards/atlasint.h> 23 23 24 - #define PCIA ATLASINT_PCIA 25 - #define PCIB ATLASINT_PCIB 26 - #define PCIC ATLASINT_PCIC 27 - #define PCID ATLASINT_PCID 28 - #define INTA ATLASINT_INTA 29 - #define INTB ATLASINT_INTB 30 - #define ETH ATLASINT_ETH 31 - #define INTC ATLASINT_INTC 32 - #define SCSI ATLASINT_SCSI 33 - #define INTD ATLASINT_INTD 24 + #define PCIA ATLAS_INT_PCIA 25 + #define PCIB ATLAS_INT_PCIB 26 + #define PCIC ATLAS_INT_PCIC 27 + #define PCID ATLAS_INT_PCID 28 + #define INTA ATLAS_INT_INTA 29 + #define INTB ATLAS_INT_INTB 30 + #define ETH ATLAS_INT_ETH 31 + #define INTC ATLAS_INT_INTC 32 + #define SCSI ATLAS_INT_SCSI 33 + #define INTD ATLAS_INT_INTD 34 34 35 35 static char irq_tab[][5] __initdata = { 36 36 /* INTA INTB INTC INTD */
+1 -1
include/asm-mips/mach-atlas/mc146818rtc.h
··· 33 33 #define RTC_PORT(x) (ATLAS_RTC_ADR_REG + (x) * 8) 34 34 #define RTC_IO_EXTENT 0x100 35 35 #define RTC_IOMAPPED 0 36 - #define RTC_IRQ ATLASINT_RTC 36 + #define RTC_IRQ ATLAS_INT_RTC 37 37 38 38 static inline unsigned char CMOS_READ(unsigned long addr) 39 39 {
+86 -38
include/asm-mips/mips-boards/atlasint.h
··· 1 1 /* 2 - * Carsten Langgaard, carstenl@mips.com 3 - * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. 2 + * Copyright (C) 1999, 2006 MIPS Technologies, Inc. All rights reserved. 3 + * Authors: Carsten Langgaard <carstenl@mips.com> 4 + * Maciej W. Rozycki <macro@mips.com> 4 5 * 5 6 * ######################################################################## 6 7 * ··· 26 25 #ifndef _MIPS_ATLASINT_H 27 26 #define _MIPS_ATLASINT_H 28 27 29 - #define ATLASINT_BASE 1 30 - #define ATLASINT_UART (ATLASINT_BASE+0) 31 - #define ATLASINT_TIM0 (ATLASINT_BASE+1) 32 - #define ATLASINT_RES2 (ATLASINT_BASE+2) 33 - #define ATLASINT_RES3 (ATLASINT_BASE+3) 34 - #define ATLASINT_RTC (ATLASINT_BASE+4) 35 - #define ATLASINT_COREHI (ATLASINT_BASE+5) 36 - #define ATLASINT_CORELO (ATLASINT_BASE+6) 37 - #define ATLASINT_RES7 (ATLASINT_BASE+7) 38 - #define ATLASINT_PCIA (ATLASINT_BASE+8) 39 - #define ATLASINT_PCIB (ATLASINT_BASE+9) 40 - #define ATLASINT_PCIC (ATLASINT_BASE+10) 41 - #define ATLASINT_PCID (ATLASINT_BASE+11) 42 - #define ATLASINT_ENUM (ATLASINT_BASE+12) 43 - #define ATLASINT_DEG (ATLASINT_BASE+13) 44 - #define ATLASINT_ATXFAIL (ATLASINT_BASE+14) 45 - #define ATLASINT_INTA (ATLASINT_BASE+15) 46 - #define ATLASINT_INTB (ATLASINT_BASE+16) 47 - #define ATLASINT_ETH ATLASINT_INTB 48 - #define ATLASINT_INTC (ATLASINT_BASE+17) 49 - #define ATLASINT_SCSI ATLASINT_INTC 50 - #define ATLASINT_INTD (ATLASINT_BASE+18) 51 - #define ATLASINT_SERR (ATLASINT_BASE+19) 52 - #define ATLASINT_RES20 (ATLASINT_BASE+20) 53 - #define ATLASINT_RES21 (ATLASINT_BASE+21) 54 - #define ATLASINT_RES22 (ATLASINT_BASE+22) 55 - #define ATLASINT_RES23 (ATLASINT_BASE+23) 56 - #define ATLASINT_RES24 (ATLASINT_BASE+24) 57 - #define ATLASINT_RES25 (ATLASINT_BASE+25) 58 - #define ATLASINT_RES26 (ATLASINT_BASE+26) 59 - #define ATLASINT_RES27 (ATLASINT_BASE+27) 60 - #define ATLASINT_RES28 (ATLASINT_BASE+28) 61 - #define ATLASINT_RES29 (ATLASINT_BASE+29) 62 - #define ATLASINT_RES30 (ATLASINT_BASE+30) 63 - #define ATLASINT_RES31 (ATLASINT_BASE+31) 64 - #define ATLASINT_END (ATLASINT_BASE+31) 28 + /* 29 + * Interrupts 0..7 are used for Atlas CPU interrupts (nonEIC mode) 30 + */ 31 + #define MIPSCPU_INT_BASE 0 32 + 33 + /* CPU interrupt offsets */ 34 + #define MIPSCPU_INT_SW0 0 35 + #define MIPSCPU_INT_SW1 1 36 + #define MIPSCPU_INT_MB0 2 37 + #define MIPSCPU_INT_ATLAS MIPSCPU_INT_MB0 38 + #define MIPSCPU_INT_MB1 3 39 + #define MIPSCPU_INT_MB2 4 40 + #define MIPSCPU_INT_MB3 5 41 + #define MIPSCPU_INT_MB4 6 42 + #define MIPSCPU_INT_CPUCTR 7 43 + 44 + /* 45 + * Interrupts 8..39 are used for Atlas interrupt controller interrupts 46 + */ 47 + #define ATLAS_INT_BASE 8 48 + #define ATLAS_INT_UART (ATLAS_INT_BASE + 0) 49 + #define ATLAS_INT_TIM0 (ATLAS_INT_BASE + 1) 50 + #define ATLAS_INT_RES2 (ATLAS_INT_BASE + 2) 51 + #define ATLAS_INT_RES3 (ATLAS_INT_BASE + 3) 52 + #define ATLAS_INT_RTC (ATLAS_INT_BASE + 4) 53 + #define ATLAS_INT_COREHI (ATLAS_INT_BASE + 5) 54 + #define ATLAS_INT_CORELO (ATLAS_INT_BASE + 6) 55 + #define ATLAS_INT_RES7 (ATLAS_INT_BASE + 7) 56 + #define ATLAS_INT_PCIA (ATLAS_INT_BASE + 8) 57 + #define ATLAS_INT_PCIB (ATLAS_INT_BASE + 9) 58 + #define ATLAS_INT_PCIC (ATLAS_INT_BASE + 10) 59 + #define ATLAS_INT_PCID (ATLAS_INT_BASE + 11) 60 + #define ATLAS_INT_ENUM (ATLAS_INT_BASE + 12) 61 + #define ATLAS_INT_DEG (ATLAS_INT_BASE + 13) 62 + #define ATLAS_INT_ATXFAIL (ATLAS_INT_BASE + 14) 63 + #define ATLAS_INT_INTA (ATLAS_INT_BASE + 15) 64 + #define ATLAS_INT_INTB (ATLAS_INT_BASE + 16) 65 + #define ATLAS_INT_ETH ATLAS_INT_INTB 66 + #define ATLAS_INT_INTC (ATLAS_INT_BASE + 17) 67 + #define ATLAS_INT_SCSI ATLAS_INT_INTC 68 + #define ATLAS_INT_INTD (ATLAS_INT_BASE + 18) 69 + #define ATLAS_INT_SERR (ATLAS_INT_BASE + 19) 70 + #define ATLAS_INT_RES20 (ATLAS_INT_BASE + 20) 71 + #define ATLAS_INT_RES21 (ATLAS_INT_BASE + 21) 72 + #define ATLAS_INT_RES22 (ATLAS_INT_BASE + 22) 73 + #define ATLAS_INT_RES23 (ATLAS_INT_BASE + 23) 74 + #define ATLAS_INT_RES24 (ATLAS_INT_BASE + 24) 75 + #define ATLAS_INT_RES25 (ATLAS_INT_BASE + 25) 76 + #define ATLAS_INT_RES26 (ATLAS_INT_BASE + 26) 77 + #define ATLAS_INT_RES27 (ATLAS_INT_BASE + 27) 78 + #define ATLAS_INT_RES28 (ATLAS_INT_BASE + 28) 79 + #define ATLAS_INT_RES29 (ATLAS_INT_BASE + 29) 80 + #define ATLAS_INT_RES30 (ATLAS_INT_BASE + 30) 81 + #define ATLAS_INT_RES31 (ATLAS_INT_BASE + 31) 82 + #define ATLAS_INT_END (ATLAS_INT_BASE + 31) 83 + 84 + /* 85 + * Interrupts 64..127 are used for Soc-it Classic interrupts 86 + */ 87 + #define MSC01C_INT_BASE 64 88 + 89 + /* SOC-it Classic interrupt offsets */ 90 + #define MSC01C_INT_TMR 0 91 + #define MSC01C_INT_PCI 1 92 + 93 + /* 94 + * Interrupts 64..127 are used for Soc-it EIC interrupts 95 + */ 96 + #define MSC01E_INT_BASE 64 97 + 98 + /* SOC-it EIC interrupt offsets */ 99 + #define MSC01E_INT_SW0 1 100 + #define MSC01E_INT_SW1 2 101 + #define MSC01E_INT_MB0 3 102 + #define MSC01E_INT_ATLAS MSC01E_INT_MB0 103 + #define MSC01E_INT_MB1 4 104 + #define MSC01E_INT_MB2 5 105 + #define MSC01E_INT_MB3 6 106 + #define MSC01E_INT_MB4 7 107 + #define MSC01E_INT_TMR 8 108 + #define MSC01E_INT_PCI 9 109 + #define MSC01E_INT_PERFCTR 10 110 + #define MSC01E_INT_CPUCTR 11 65 111 66 112 #endif /* !(_MIPS_ATLASINT_H) */