11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * ip22-int.c: Routines for generic manipulation of the INT[23] ASIC 31da177e4SLinus Torvalds * found on INDY and Indigo2 workstations. 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 61da177e4SLinus Torvalds * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) 71da177e4SLinus Torvalds * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) 81da177e4SLinus Torvalds * - Indigo2 changes 91da177e4SLinus Torvalds * - Interrupt handling fixes 101da177e4SLinus Torvalds * Copyright (C) 2001, 2003 Ladislav Michl (ladis@linux-mips.org) 111da177e4SLinus Torvalds */ 121da177e4SLinus Torvalds #include <linux/config.h> 131da177e4SLinus Torvalds #include <linux/types.h> 141da177e4SLinus Torvalds #include <linux/init.h> 151da177e4SLinus Torvalds #include <linux/kernel_stat.h> 161da177e4SLinus Torvalds #include <linux/signal.h> 171da177e4SLinus Torvalds #include <linux/sched.h> 181da177e4SLinus Torvalds #include <linux/interrupt.h> 191da177e4SLinus Torvalds #include <linux/irq.h> 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds #include <asm/mipsregs.h> 221da177e4SLinus Torvalds #include <asm/addrspace.h> 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds #include <asm/sgi/ioc.h> 251da177e4SLinus Torvalds #include <asm/sgi/hpc3.h> 261da177e4SLinus Torvalds #include <asm/sgi/ip22.h> 271da177e4SLinus Torvalds 281da177e4SLinus Torvalds /* #define DEBUG_SGINT */ 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds /* So far nothing hangs here */ 311da177e4SLinus Torvalds #undef USE_LIO3_IRQ 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds struct sgint_regs *sgint; 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds static char lc0msk_to_irqnr[256]; 361da177e4SLinus Torvalds static char lc1msk_to_irqnr[256]; 371da177e4SLinus Torvalds static char lc2msk_to_irqnr[256]; 381da177e4SLinus Torvalds static char lc3msk_to_irqnr[256]; 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds extern int ip22_eisa_init(void); 411da177e4SLinus Torvalds 421da177e4SLinus Torvalds static void enable_local0_irq(unsigned int irq) 431da177e4SLinus Torvalds { 441da177e4SLinus Torvalds unsigned long flags; 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds local_irq_save(flags); 471da177e4SLinus Torvalds /* don't allow mappable interrupt to be enabled from setup_irq, 481da177e4SLinus Torvalds * we have our own way to do so */ 491da177e4SLinus Torvalds if (irq != SGI_MAP_0_IRQ) 501da177e4SLinus Torvalds sgint->imask0 |= (1 << (irq - SGINT_LOCAL0)); 511da177e4SLinus Torvalds local_irq_restore(flags); 521da177e4SLinus Torvalds } 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds static unsigned int startup_local0_irq(unsigned int irq) 551da177e4SLinus Torvalds { 561da177e4SLinus Torvalds enable_local0_irq(irq); 571da177e4SLinus Torvalds return 0; /* Never anything pending */ 581da177e4SLinus Torvalds } 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds static void disable_local0_irq(unsigned int irq) 611da177e4SLinus Torvalds { 621da177e4SLinus Torvalds unsigned long flags; 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds local_irq_save(flags); 651da177e4SLinus Torvalds sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); 661da177e4SLinus Torvalds local_irq_restore(flags); 671da177e4SLinus Torvalds } 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds #define shutdown_local0_irq disable_local0_irq 701da177e4SLinus Torvalds #define mask_and_ack_local0_irq disable_local0_irq 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds static void end_local0_irq (unsigned int irq) 731da177e4SLinus Torvalds { 741da177e4SLinus Torvalds if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 751da177e4SLinus Torvalds enable_local0_irq(irq); 761da177e4SLinus Torvalds } 771da177e4SLinus Torvalds 781da177e4SLinus Torvalds static struct hw_interrupt_type ip22_local0_irq_type = { 791da177e4SLinus Torvalds .typename = "IP22 local 0", 801da177e4SLinus Torvalds .startup = startup_local0_irq, 811da177e4SLinus Torvalds .shutdown = shutdown_local0_irq, 821da177e4SLinus Torvalds .enable = enable_local0_irq, 831da177e4SLinus Torvalds .disable = disable_local0_irq, 841da177e4SLinus Torvalds .ack = mask_and_ack_local0_irq, 851da177e4SLinus Torvalds .end = end_local0_irq, 861da177e4SLinus Torvalds }; 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds static void enable_local1_irq(unsigned int irq) 891da177e4SLinus Torvalds { 901da177e4SLinus Torvalds unsigned long flags; 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds local_irq_save(flags); 931da177e4SLinus Torvalds /* don't allow mappable interrupt to be enabled from setup_irq, 941da177e4SLinus Torvalds * we have our own way to do so */ 951da177e4SLinus Torvalds if (irq != SGI_MAP_1_IRQ) 961da177e4SLinus Torvalds sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); 971da177e4SLinus Torvalds local_irq_restore(flags); 981da177e4SLinus Torvalds } 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds static unsigned int startup_local1_irq(unsigned int irq) 1011da177e4SLinus Torvalds { 1021da177e4SLinus Torvalds enable_local1_irq(irq); 1031da177e4SLinus Torvalds return 0; /* Never anything pending */ 1041da177e4SLinus Torvalds } 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds void disable_local1_irq(unsigned int irq) 1071da177e4SLinus Torvalds { 1081da177e4SLinus Torvalds unsigned long flags; 1091da177e4SLinus Torvalds 1101da177e4SLinus Torvalds local_irq_save(flags); 1111da177e4SLinus Torvalds sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); 1121da177e4SLinus Torvalds local_irq_restore(flags); 1131da177e4SLinus Torvalds } 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds #define shutdown_local1_irq disable_local1_irq 1161da177e4SLinus Torvalds #define mask_and_ack_local1_irq disable_local1_irq 1171da177e4SLinus Torvalds 1181da177e4SLinus Torvalds static void end_local1_irq (unsigned int irq) 1191da177e4SLinus Torvalds { 1201da177e4SLinus Torvalds if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 1211da177e4SLinus Torvalds enable_local1_irq(irq); 1221da177e4SLinus Torvalds } 1231da177e4SLinus Torvalds 1241da177e4SLinus Torvalds static struct hw_interrupt_type ip22_local1_irq_type = { 1251da177e4SLinus Torvalds .typename = "IP22 local 1", 1261da177e4SLinus Torvalds .startup = startup_local1_irq, 1271da177e4SLinus Torvalds .shutdown = shutdown_local1_irq, 1281da177e4SLinus Torvalds .enable = enable_local1_irq, 1291da177e4SLinus Torvalds .disable = disable_local1_irq, 1301da177e4SLinus Torvalds .ack = mask_and_ack_local1_irq, 1311da177e4SLinus Torvalds .end = end_local1_irq, 1321da177e4SLinus Torvalds }; 1331da177e4SLinus Torvalds 1341da177e4SLinus Torvalds static void enable_local2_irq(unsigned int irq) 1351da177e4SLinus Torvalds { 1361da177e4SLinus Torvalds unsigned long flags; 1371da177e4SLinus Torvalds 1381da177e4SLinus Torvalds local_irq_save(flags); 1391da177e4SLinus Torvalds sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); 1401da177e4SLinus Torvalds sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); 1411da177e4SLinus Torvalds local_irq_restore(flags); 1421da177e4SLinus Torvalds } 1431da177e4SLinus Torvalds 1441da177e4SLinus Torvalds static unsigned int startup_local2_irq(unsigned int irq) 1451da177e4SLinus Torvalds { 1461da177e4SLinus Torvalds enable_local2_irq(irq); 1471da177e4SLinus Torvalds return 0; /* Never anything pending */ 1481da177e4SLinus Torvalds } 1491da177e4SLinus Torvalds 1501da177e4SLinus Torvalds void disable_local2_irq(unsigned int irq) 1511da177e4SLinus Torvalds { 1521da177e4SLinus Torvalds unsigned long flags; 1531da177e4SLinus Torvalds 1541da177e4SLinus Torvalds local_irq_save(flags); 1551da177e4SLinus Torvalds sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); 1561da177e4SLinus Torvalds if (!sgint->cmeimask0) 1571da177e4SLinus Torvalds sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); 1581da177e4SLinus Torvalds local_irq_restore(flags); 1591da177e4SLinus Torvalds } 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds #define shutdown_local2_irq disable_local2_irq 1621da177e4SLinus Torvalds #define mask_and_ack_local2_irq disable_local2_irq 1631da177e4SLinus Torvalds 1641da177e4SLinus Torvalds static void end_local2_irq (unsigned int irq) 1651da177e4SLinus Torvalds { 1661da177e4SLinus Torvalds if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 1671da177e4SLinus Torvalds enable_local2_irq(irq); 1681da177e4SLinus Torvalds } 1691da177e4SLinus Torvalds 1701da177e4SLinus Torvalds static struct hw_interrupt_type ip22_local2_irq_type = { 1711da177e4SLinus Torvalds .typename = "IP22 local 2", 1721da177e4SLinus Torvalds .startup = startup_local2_irq, 1731da177e4SLinus Torvalds .shutdown = shutdown_local2_irq, 1741da177e4SLinus Torvalds .enable = enable_local2_irq, 1751da177e4SLinus Torvalds .disable = disable_local2_irq, 1761da177e4SLinus Torvalds .ack = mask_and_ack_local2_irq, 1771da177e4SLinus Torvalds .end = end_local2_irq, 1781da177e4SLinus Torvalds }; 1791da177e4SLinus Torvalds 1801da177e4SLinus Torvalds static void enable_local3_irq(unsigned int irq) 1811da177e4SLinus Torvalds { 1821da177e4SLinus Torvalds unsigned long flags; 1831da177e4SLinus Torvalds 1841da177e4SLinus Torvalds local_irq_save(flags); 1851da177e4SLinus Torvalds sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); 1861da177e4SLinus Torvalds sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); 1871da177e4SLinus Torvalds local_irq_restore(flags); 1881da177e4SLinus Torvalds } 1891da177e4SLinus Torvalds 1901da177e4SLinus Torvalds static unsigned int startup_local3_irq(unsigned int irq) 1911da177e4SLinus Torvalds { 1921da177e4SLinus Torvalds enable_local3_irq(irq); 1931da177e4SLinus Torvalds return 0; /* Never anything pending */ 1941da177e4SLinus Torvalds } 1951da177e4SLinus Torvalds 1961da177e4SLinus Torvalds void disable_local3_irq(unsigned int irq) 1971da177e4SLinus Torvalds { 1981da177e4SLinus Torvalds unsigned long flags; 1991da177e4SLinus Torvalds 2001da177e4SLinus Torvalds local_irq_save(flags); 2011da177e4SLinus Torvalds sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); 2021da177e4SLinus Torvalds if (!sgint->cmeimask1) 2031da177e4SLinus Torvalds sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); 2041da177e4SLinus Torvalds local_irq_restore(flags); 2051da177e4SLinus Torvalds } 2061da177e4SLinus Torvalds 2071da177e4SLinus Torvalds #define shutdown_local3_irq disable_local3_irq 2081da177e4SLinus Torvalds #define mask_and_ack_local3_irq disable_local3_irq 2091da177e4SLinus Torvalds 2101da177e4SLinus Torvalds static void end_local3_irq (unsigned int irq) 2111da177e4SLinus Torvalds { 2121da177e4SLinus Torvalds if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 2131da177e4SLinus Torvalds enable_local3_irq(irq); 2141da177e4SLinus Torvalds } 2151da177e4SLinus Torvalds 2161da177e4SLinus Torvalds static struct hw_interrupt_type ip22_local3_irq_type = { 2171da177e4SLinus Torvalds .typename = "IP22 local 3", 2181da177e4SLinus Torvalds .startup = startup_local3_irq, 2191da177e4SLinus Torvalds .shutdown = shutdown_local3_irq, 2201da177e4SLinus Torvalds .enable = enable_local3_irq, 2211da177e4SLinus Torvalds .disable = disable_local3_irq, 2221da177e4SLinus Torvalds .ack = mask_and_ack_local3_irq, 2231da177e4SLinus Torvalds .end = end_local3_irq, 2241da177e4SLinus Torvalds }; 2251da177e4SLinus Torvalds 226e4ac58afSRalf Baechle static void indy_local0_irqdispatch(struct pt_regs *regs) 2271da177e4SLinus Torvalds { 2281da177e4SLinus Torvalds u8 mask = sgint->istat0 & sgint->imask0; 2291da177e4SLinus Torvalds u8 mask2; 2301da177e4SLinus Torvalds int irq; 2311da177e4SLinus Torvalds 2321da177e4SLinus Torvalds if (mask & SGINT_ISTAT0_LIO2) { 2331da177e4SLinus Torvalds mask2 = sgint->vmeistat & sgint->cmeimask0; 2341da177e4SLinus Torvalds irq = lc2msk_to_irqnr[mask2]; 2351da177e4SLinus Torvalds } else 2361da177e4SLinus Torvalds irq = lc0msk_to_irqnr[mask]; 2371da177e4SLinus Torvalds 2381da177e4SLinus Torvalds /* if irq == 0, then the interrupt has already been cleared */ 2391da177e4SLinus Torvalds if (irq) 2401da177e4SLinus Torvalds do_IRQ(irq, regs); 2411da177e4SLinus Torvalds return; 2421da177e4SLinus Torvalds } 2431da177e4SLinus Torvalds 244e4ac58afSRalf Baechle static void indy_local1_irqdispatch(struct pt_regs *regs) 2451da177e4SLinus Torvalds { 2461da177e4SLinus Torvalds u8 mask = sgint->istat1 & sgint->imask1; 2471da177e4SLinus Torvalds u8 mask2; 2481da177e4SLinus Torvalds int irq; 2491da177e4SLinus Torvalds 2501da177e4SLinus Torvalds if (mask & SGINT_ISTAT1_LIO3) { 2511da177e4SLinus Torvalds mask2 = sgint->vmeistat & sgint->cmeimask1; 2521da177e4SLinus Torvalds irq = lc3msk_to_irqnr[mask2]; 2531da177e4SLinus Torvalds } else 2541da177e4SLinus Torvalds irq = lc1msk_to_irqnr[mask]; 2551da177e4SLinus Torvalds 2561da177e4SLinus Torvalds /* if irq == 0, then the interrupt has already been cleared */ 2571da177e4SLinus Torvalds if (irq) 2581da177e4SLinus Torvalds do_IRQ(irq, regs); 2591da177e4SLinus Torvalds return; 2601da177e4SLinus Torvalds } 2611da177e4SLinus Torvalds 2621da177e4SLinus Torvalds extern void ip22_be_interrupt(int irq, struct pt_regs *regs); 2631da177e4SLinus Torvalds 264e4ac58afSRalf Baechle static void indy_buserror_irq(struct pt_regs *regs) 2651da177e4SLinus Torvalds { 2661da177e4SLinus Torvalds int irq = SGI_BUSERR_IRQ; 2671da177e4SLinus Torvalds 2681da177e4SLinus Torvalds irq_enter(); 2691da177e4SLinus Torvalds kstat_this_cpu.irqs[irq]++; 2701da177e4SLinus Torvalds ip22_be_interrupt(irq, regs); 2711da177e4SLinus Torvalds irq_exit(); 2721da177e4SLinus Torvalds } 2731da177e4SLinus Torvalds 2741da177e4SLinus Torvalds static struct irqaction local0_cascade = { 2751da177e4SLinus Torvalds .handler = no_action, 2761da177e4SLinus Torvalds .flags = SA_INTERRUPT, 2771da177e4SLinus Torvalds .name = "local0 cascade", 2781da177e4SLinus Torvalds }; 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvalds static struct irqaction local1_cascade = { 2811da177e4SLinus Torvalds .handler = no_action, 2821da177e4SLinus Torvalds .flags = SA_INTERRUPT, 2831da177e4SLinus Torvalds .name = "local1 cascade", 2841da177e4SLinus Torvalds }; 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds static struct irqaction buserr = { 2871da177e4SLinus Torvalds .handler = no_action, 2881da177e4SLinus Torvalds .flags = SA_INTERRUPT, 2891da177e4SLinus Torvalds .name = "Bus Error", 2901da177e4SLinus Torvalds }; 2911da177e4SLinus Torvalds 2921da177e4SLinus Torvalds static struct irqaction map0_cascade = { 2931da177e4SLinus Torvalds .handler = no_action, 2941da177e4SLinus Torvalds .flags = SA_INTERRUPT, 2951da177e4SLinus Torvalds .name = "mapable0 cascade", 2961da177e4SLinus Torvalds }; 2971da177e4SLinus Torvalds 2981da177e4SLinus Torvalds #ifdef USE_LIO3_IRQ 2991da177e4SLinus Torvalds static struct irqaction map1_cascade = { 3001da177e4SLinus Torvalds .handler = no_action, 3011da177e4SLinus Torvalds .flags = SA_INTERRUPT, 3021da177e4SLinus Torvalds .name = "mapable1 cascade", 3031da177e4SLinus Torvalds }; 3041da177e4SLinus Torvalds #define SGI_INTERRUPTS SGINT_END 3051da177e4SLinus Torvalds #else 3061da177e4SLinus Torvalds #define SGI_INTERRUPTS SGINT_LOCAL3 3071da177e4SLinus Torvalds #endif 3081da177e4SLinus Torvalds 309e4ac58afSRalf Baechle extern void indy_r4k_timer_interrupt(struct pt_regs *regs); 310e4ac58afSRalf Baechle extern void indy_8254timer_irq(struct pt_regs *regs); 311e4ac58afSRalf Baechle 312e4ac58afSRalf Baechle /* 313e4ac58afSRalf Baechle * IRQs on the INDY look basically (barring software IRQs which we don't use 314e4ac58afSRalf Baechle * at all) like: 315e4ac58afSRalf Baechle * 316e4ac58afSRalf Baechle * MIPS IRQ Source 317e4ac58afSRalf Baechle * -------- ------ 318e4ac58afSRalf Baechle * 0 Software (ignored) 319e4ac58afSRalf Baechle * 1 Software (ignored) 320e4ac58afSRalf Baechle * 2 Local IRQ level zero 321e4ac58afSRalf Baechle * 3 Local IRQ level one 322e4ac58afSRalf Baechle * 4 8254 Timer zero 323e4ac58afSRalf Baechle * 5 8254 Timer one 324e4ac58afSRalf Baechle * 6 Bus Error 325e4ac58afSRalf Baechle * 7 R4k timer (what we use) 326e4ac58afSRalf Baechle * 327e4ac58afSRalf Baechle * We handle the IRQ according to _our_ priority which is: 328e4ac58afSRalf Baechle * 329e4ac58afSRalf Baechle * Highest ---- R4k Timer 330e4ac58afSRalf Baechle * Local IRQ zero 331e4ac58afSRalf Baechle * Local IRQ one 332e4ac58afSRalf Baechle * Bus Error 333e4ac58afSRalf Baechle * 8254 Timer zero 334e4ac58afSRalf Baechle * Lowest ---- 8254 Timer one 335e4ac58afSRalf Baechle * 336e4ac58afSRalf Baechle * then we just return, if multiple IRQs are pending then we will just take 337e4ac58afSRalf Baechle * another exception, big deal. 338e4ac58afSRalf Baechle */ 339e4ac58afSRalf Baechle 340e4ac58afSRalf Baechle asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 341e4ac58afSRalf Baechle { 342e4ac58afSRalf Baechle unsigned int pending = read_c0_cause(); 343e4ac58afSRalf Baechle 344e4ac58afSRalf Baechle /* 345e4ac58afSRalf Baechle * First we check for r4k counter/timer IRQ. 346e4ac58afSRalf Baechle */ 347e4ac58afSRalf Baechle if (pending & CAUSEF_IP7) 348e4ac58afSRalf Baechle indy_r4k_timer_interrupt(regs); 349e4ac58afSRalf Baechle else if (pending & CAUSEF_IP2) 350e4ac58afSRalf Baechle indy_local0_irqdispatch(regs); 351e4ac58afSRalf Baechle else if (pending & CAUSEF_IP3) 352e4ac58afSRalf Baechle indy_local1_irqdispatch(regs); 353e4ac58afSRalf Baechle else if (pending & CAUSEF_IP6) 354e4ac58afSRalf Baechle indy_buserror_irq(regs); 355e4ac58afSRalf Baechle else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) 356e4ac58afSRalf Baechle indy_8254timer_irq(regs); 357e4ac58afSRalf Baechle } 358e4ac58afSRalf Baechle 3591da177e4SLinus Torvalds extern void mips_cpu_irq_init(unsigned int irq_base); 3601da177e4SLinus Torvalds 3611da177e4SLinus Torvalds void __init arch_init_irq(void) 3621da177e4SLinus Torvalds { 3631da177e4SLinus Torvalds int i; 3641da177e4SLinus Torvalds 3651da177e4SLinus Torvalds /* Init local mask --> irq tables. */ 3661da177e4SLinus Torvalds for (i = 0; i < 256; i++) { 3671da177e4SLinus Torvalds if (i & 0x80) { 3681da177e4SLinus Torvalds lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7; 3691da177e4SLinus Torvalds lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7; 3701da177e4SLinus Torvalds lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7; 3711da177e4SLinus Torvalds lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7; 3721da177e4SLinus Torvalds } else if (i & 0x40) { 3731da177e4SLinus Torvalds lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6; 3741da177e4SLinus Torvalds lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6; 3751da177e4SLinus Torvalds lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6; 3761da177e4SLinus Torvalds lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6; 3771da177e4SLinus Torvalds } else if (i & 0x20) { 3781da177e4SLinus Torvalds lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5; 3791da177e4SLinus Torvalds lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5; 3801da177e4SLinus Torvalds lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5; 3811da177e4SLinus Torvalds lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5; 3821da177e4SLinus Torvalds } else if (i & 0x10) { 3831da177e4SLinus Torvalds lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4; 3841da177e4SLinus Torvalds lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4; 3851da177e4SLinus Torvalds lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4; 3861da177e4SLinus Torvalds lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4; 3871da177e4SLinus Torvalds } else if (i & 0x08) { 3881da177e4SLinus Torvalds lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3; 3891da177e4SLinus Torvalds lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3; 3901da177e4SLinus Torvalds lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3; 3911da177e4SLinus Torvalds lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3; 3921da177e4SLinus Torvalds } else if (i & 0x04) { 3931da177e4SLinus Torvalds lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2; 3941da177e4SLinus Torvalds lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2; 3951da177e4SLinus Torvalds lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2; 3961da177e4SLinus Torvalds lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2; 3971da177e4SLinus Torvalds } else if (i & 0x02) { 3981da177e4SLinus Torvalds lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1; 3991da177e4SLinus Torvalds lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1; 4001da177e4SLinus Torvalds lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1; 4011da177e4SLinus Torvalds lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1; 4021da177e4SLinus Torvalds } else if (i & 0x01) { 4031da177e4SLinus Torvalds lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0; 4041da177e4SLinus Torvalds lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0; 4051da177e4SLinus Torvalds lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0; 4061da177e4SLinus Torvalds lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0; 4071da177e4SLinus Torvalds } else { 4081da177e4SLinus Torvalds lc0msk_to_irqnr[i] = 0; 4091da177e4SLinus Torvalds lc1msk_to_irqnr[i] = 0; 4101da177e4SLinus Torvalds lc2msk_to_irqnr[i] = 0; 4111da177e4SLinus Torvalds lc3msk_to_irqnr[i] = 0; 4121da177e4SLinus Torvalds } 4131da177e4SLinus Torvalds } 4141da177e4SLinus Torvalds 4151da177e4SLinus Torvalds /* Mask out all interrupts. */ 4161da177e4SLinus Torvalds sgint->imask0 = 0; 4171da177e4SLinus Torvalds sgint->imask1 = 0; 4181da177e4SLinus Torvalds sgint->cmeimask0 = 0; 4191da177e4SLinus Torvalds sgint->cmeimask1 = 0; 4201da177e4SLinus Torvalds 4211da177e4SLinus Torvalds /* init CPU irqs */ 4221da177e4SLinus Torvalds mips_cpu_irq_init(SGINT_CPU); 4231da177e4SLinus Torvalds 4241da177e4SLinus Torvalds for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) { 4251da177e4SLinus Torvalds hw_irq_controller *handler; 4261da177e4SLinus Torvalds 4271da177e4SLinus Torvalds if (i < SGINT_LOCAL1) 4281da177e4SLinus Torvalds handler = &ip22_local0_irq_type; 4291da177e4SLinus Torvalds else if (i < SGINT_LOCAL2) 4301da177e4SLinus Torvalds handler = &ip22_local1_irq_type; 4311da177e4SLinus Torvalds else if (i < SGINT_LOCAL3) 4321da177e4SLinus Torvalds handler = &ip22_local2_irq_type; 4331da177e4SLinus Torvalds else 4341da177e4SLinus Torvalds handler = &ip22_local3_irq_type; 4351da177e4SLinus Torvalds 4361da177e4SLinus Torvalds irq_desc[i].status = IRQ_DISABLED; 4371da177e4SLinus Torvalds irq_desc[i].action = 0; 4381da177e4SLinus Torvalds irq_desc[i].depth = 1; 439*d1bef4edSIngo Molnar irq_desc[i].chip = handler; 4401da177e4SLinus Torvalds } 4411da177e4SLinus Torvalds 4421da177e4SLinus Torvalds /* vector handler. this register the IRQ as non-sharable */ 4431da177e4SLinus Torvalds setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade); 4441da177e4SLinus Torvalds setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade); 4451da177e4SLinus Torvalds setup_irq(SGI_BUSERR_IRQ, &buserr); 4461da177e4SLinus Torvalds 4471da177e4SLinus Torvalds /* cascade in cascade. i love Indy ;-) */ 4481da177e4SLinus Torvalds setup_irq(SGI_MAP_0_IRQ, &map0_cascade); 4491da177e4SLinus Torvalds #ifdef USE_LIO3_IRQ 4501da177e4SLinus Torvalds setup_irq(SGI_MAP_1_IRQ, &map1_cascade); 4511da177e4SLinus Torvalds #endif 4521da177e4SLinus Torvalds 4531da177e4SLinus Torvalds #ifdef CONFIG_EISA 4541da177e4SLinus Torvalds if (ip22_is_fullhouse()) /* Only Indigo-2 has EISA stuff */ 4551da177e4SLinus Torvalds ip22_eisa_init (); 4561da177e4SLinus Torvalds #endif 4571da177e4SLinus Torvalds } 458