• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/mips/pmc-sierra/msp71xx/
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