1/* 2 * IRQ vector handles 3 * 4 * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/irq.h> 14#include <linux/interrupt.h> 15#include <linux/ptrace.h> 16#include <linux/time.h> 17 18#include <asm/irq_cpu.h> 19 20#include <msp_int.h> 21 22extern void msp_int_handle(void); 23 24/* SLP bases systems */ 25extern void msp_slp_irq_init(void); 26extern void msp_slp_irq_dispatch(void); 27 28/* CIC based systems */ 29extern void msp_cic_irq_init(void); 30extern void msp_cic_irq_dispatch(void); 31 32/* 33 * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded 34 * hierarchical system. The first level are the direct MIPS interrupts 35 * and are assigned the interrupt range 0-7. The second level is the SLM 36 * interrupt controller and is assigned the range 8-39. The third level 37 * comprises the Peripherial block, the PCI block, the PCI MSI block and 38 * the SLP. The PCI interrupts and the SLP errors are handled by the 39 * relevant subsystems so the core interrupt code needs only concern 40 * itself with the Peripheral block. These are assigned interrupts in 41 * the range 40-71. 42 */ 43 44asmlinkage void plat_irq_dispatch(struct pt_regs *regs) 45{ 46 u32 pending; 47 48 pending = read_c0_status() & read_c0_cause(); 49 50 /* 51 * jump to the correct interrupt routine 52 * These are arranged in priority order and the timer 53 * comes first! 54 */ 55 56#ifdef CONFIG_IRQ_MSP_CIC /* break out the CIC stuff for now */ 57 if (pending & C_IRQ4) /* do the peripherals first, that's the timer */ 58 msp_cic_irq_dispatch(); 59 60 else if (pending & C_IRQ0) 61 do_IRQ(MSP_INT_MAC0); 62 63 else if (pending & C_IRQ1) 64 do_IRQ(MSP_INT_MAC1); 65 66 else if (pending & C_IRQ2) 67 do_IRQ(MSP_INT_USB); 68 69 else if (pending & C_IRQ3) 70 do_IRQ(MSP_INT_SAR); 71 72 else if (pending & C_IRQ5) 73 do_IRQ(MSP_INT_SEC); 74 75#else 76 if (pending & C_IRQ5) 77 do_IRQ(MSP_INT_TIMER); 78 79 else if (pending & C_IRQ0) 80 do_IRQ(MSP_INT_MAC0); 81 82 else if (pending & C_IRQ1) 83 do_IRQ(MSP_INT_MAC1); 84 85 else if (pending & C_IRQ3) 86 do_IRQ(MSP_INT_VE); 87 88 else if (pending & C_IRQ4) 89 msp_slp_irq_dispatch(); 90#endif 91 92 else if (pending & C_SW0) /* do software after hardware */ 93 do_IRQ(MSP_INT_SW0); 94 95 else if (pending & C_SW1) 96 do_IRQ(MSP_INT_SW1); 97} 98 99static struct irqaction cascade_msp = { 100 .handler = no_action, 101 .name = "MSP cascade" 102}; 103 104 105void __init arch_init_irq(void) 106{ 107 /* initialize the 1st-level CPU based interrupt controller */ 108 mips_cpu_irq_init(); 109 110#ifdef CONFIG_IRQ_MSP_CIC 111 msp_cic_irq_init(); 112 113 /* setup the cascaded interrupts */ 114 setup_irq(MSP_INT_CIC, &cascade_msp); 115 setup_irq(MSP_INT_PER, &cascade_msp); 116#else 117 /* setup the 2nd-level SLP register based interrupt controller */ 118 msp_slp_irq_init(); 119 120 /* setup the cascaded SLP/PER interrupts */ 121 setup_irq(MSP_INT_SLP, &cascade_msp); 122 setup_irq(MSP_INT_PER, &cascade_msp); 123#endif 124} 125