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#include <asm/setup.h> 20 21#include <msp_int.h> 22 23/* SLP bases systems */ 24extern void msp_slp_irq_init(void); 25extern void msp_slp_irq_dispatch(void); 26 27/* CIC based systems */ 28extern void msp_cic_irq_init(void); 29extern void msp_cic_irq_dispatch(void); 30 31/* VSMP support init */ 32extern void msp_vsmp_int_init(void); 33 34/* vectored interrupt implementation */ 35 36/* SW0/1 interrupts are used for SMP */ 37static inline void mac0_int_dispatch(void) { do_IRQ(MSP_INT_MAC0); } 38static inline void mac1_int_dispatch(void) { do_IRQ(MSP_INT_MAC1); } 39static inline void mac2_int_dispatch(void) { do_IRQ(MSP_INT_SAR); } 40static inline void usb_int_dispatch(void) { do_IRQ(MSP_INT_USB); } 41static inline void sec_int_dispatch(void) { do_IRQ(MSP_INT_SEC); } 42 43/* 44 * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded 45 * hierarchical system. The first level are the direct MIPS interrupts 46 * and are assigned the interrupt range 0-7. The second level is the SLM 47 * interrupt controller and is assigned the range 8-39. The third level 48 * comprises the Peripherial block, the PCI block, the PCI MSI block and 49 * the SLP. The PCI interrupts and the SLP errors are handled by the 50 * relevant subsystems so the core interrupt code needs only concern 51 * itself with the Peripheral block. These are assigned interrupts in 52 * the range 40-71. 53 */ 54 55asmlinkage void plat_irq_dispatch(void) 56{ 57 u32 pending; 58 59 pending = read_c0_status() & read_c0_cause(); 60 61 /* 62 * jump to the correct interrupt routine 63 * These are arranged in priority order and the timer 64 * comes first! 65 */ 66 67#ifdef CONFIG_IRQ_MSP_CIC /* break out the CIC stuff for now */ 68 if (pending & C_IRQ4) /* do the peripherals first, that's the timer */ 69 msp_cic_irq_dispatch(); 70 71 else if (pending & C_IRQ0) 72 do_IRQ(MSP_INT_MAC0); 73 74 else if (pending & C_IRQ1) 75 do_IRQ(MSP_INT_MAC1); 76 77 else if (pending & C_IRQ2) 78 do_IRQ(MSP_INT_USB); 79 80 else if (pending & C_IRQ3) 81 do_IRQ(MSP_INT_SAR); 82 83 else if (pending & C_IRQ5) 84 do_IRQ(MSP_INT_SEC); 85 86#else 87 if (pending & C_IRQ5) 88 do_IRQ(MSP_INT_TIMER); 89 90 else if (pending & C_IRQ0) 91 do_IRQ(MSP_INT_MAC0); 92 93 else if (pending & C_IRQ1) 94 do_IRQ(MSP_INT_MAC1); 95 96 else if (pending & C_IRQ3) 97 do_IRQ(MSP_INT_VE); 98 99 else if (pending & C_IRQ4) 100 msp_slp_irq_dispatch(); 101#endif 102 103 else if (pending & C_SW0) /* do software after hardware */ 104 do_IRQ(MSP_INT_SW0); 105 106 else if (pending & C_SW1) 107 do_IRQ(MSP_INT_SW1); 108} 109 110static struct irqaction cic_cascade_msp = { 111 .handler = no_action, 112 .name = "MSP CIC cascade", 113 .flags = IRQF_NO_THREAD, 114}; 115 116static struct irqaction per_cascade_msp = { 117 .handler = no_action, 118 .name = "MSP PER cascade", 119 .flags = IRQF_NO_THREAD, 120}; 121 122void __init arch_init_irq(void) 123{ 124 /* assume we'll be using vectored interrupt mode except in UP mode*/ 125#ifdef CONFIG_MIPS_MT 126 BUG_ON(!cpu_has_vint); 127#endif 128 /* initialize the 1st-level CPU based interrupt controller */ 129 mips_cpu_irq_init(); 130 131#ifdef CONFIG_IRQ_MSP_CIC 132 msp_cic_irq_init(); 133#ifdef CONFIG_MIPS_MT 134 set_vi_handler(MSP_INT_CIC, msp_cic_irq_dispatch); 135 set_vi_handler(MSP_INT_MAC0, mac0_int_dispatch); 136 set_vi_handler(MSP_INT_MAC1, mac1_int_dispatch); 137 set_vi_handler(MSP_INT_SAR, mac2_int_dispatch); 138 set_vi_handler(MSP_INT_USB, usb_int_dispatch); 139 set_vi_handler(MSP_INT_SEC, sec_int_dispatch); 140#ifdef CONFIG_MIPS_MT_SMP 141 msp_vsmp_int_init(); 142#endif /* CONFIG_MIPS_MT_SMP */ 143#endif /* CONFIG_MIPS_MT */ 144 /* setup the cascaded interrupts */ 145 setup_irq(MSP_INT_CIC, &cic_cascade_msp); 146 setup_irq(MSP_INT_PER, &per_cascade_msp); 147 148#else 149 /* 150 * Setup the 2nd-level SLP register based interrupt controller. 151 * VSMP support support is not enabled for SLP. 152 */ 153 msp_slp_irq_init(); 154 155 /* setup the cascaded SLP/PER interrupts */ 156 setup_irq(MSP_INT_SLP, &cic_cascade_msp); 157 setup_irq(MSP_INT_PER, &per_cascade_msp); 158#endif 159} 160