blob: 05693bceaeaf23de5eb38db6eea43e5567a55198 [file] [log] [blame]
Songmao Tian42d226c2007-06-06 14:52:38 +08001/*
2 * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
3 * Author: Fuxin Zhang, zhangfx@lemote.com
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
11 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
13 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
16 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#include <linux/delay.h>
27#include <linux/io.h>
28#include <linux/irq.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31#include <linux/irq.h>
32
33#include <asm/irq_cpu.h>
34#include <asm/i8259.h>
35#include <asm/mipsregs.h>
36#include <asm/mips-boards/bonito64.h>
37
38
39/*
40 * the first level int-handler will jump here if it is a bonito irq
41 */
42static void bonito_irqdispatch(void)
43{
44 u32 int_status;
45 int i;
46
47 /* workaround the IO dma problem: let cpu looping to allow DMA finish */
48 int_status = BONITO_INTISR;
49 if (int_status & (1 << 10)) {
50 while (int_status & (1 << 10)) {
51 udelay(1);
52 int_status = BONITO_INTISR;
53 }
54 }
55
56 /* Get pending sources, masked by current enables */
57 int_status = BONITO_INTISR & BONITO_INTEN;
58
59 if (int_status != 0) {
60 i = __ffs(int_status);
61 int_status &= ~(1 << i);
62 do_IRQ(BONITO_IRQ_BASE + i);
63 }
64}
65
66static void i8259_irqdispatch(void)
67{
68 int irq;
69
70 irq = i8259_irq();
71 if (irq >= 0) {
72 do_IRQ(irq);
73 } else {
74 spurious_interrupt();
75 }
76
77}
78
79asmlinkage void plat_irq_dispatch(void)
80{
81 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
82
83 if (pending & CAUSEF_IP7) {
84 do_IRQ(MIPS_CPU_IRQ_BASE + 7);
85 } else if (pending & CAUSEF_IP5) {
86 i8259_irqdispatch();
87 } else if (pending & CAUSEF_IP2) {
88 bonito_irqdispatch();
89 } else {
90 spurious_interrupt();
91 }
92}
93
94static struct irqaction cascade_irqaction = {
95 .handler = no_action,
96 .mask = CPU_MASK_NONE,
97 .name = "cascade",
98};
99
100void __init arch_init_irq(void)
101{
102 extern void bonito_irq_init(void);
103
104 /*
105 * Clear all of the interrupts while we change the able around a bit.
106 * int-handler is not on bootstrap
107 */
108 clear_c0_status(ST0_IM | ST0_BEV);
109 local_irq_disable();
110
111 /* most bonito irq should be level triggered */
112 BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
113 BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
114 BONITO_INTSTEER = 0;
115
116 /*
117 * Mask out all interrupt by writing "1" to all bit position in
118 * the interrupt reset reg.
119 */
120 BONITO_INTENCLR = ~0;
121
122 /* init all controller
123 * 0-15 ------> i8259 interrupt
124 * 16-23 ------> mips cpu interrupt
125 * 32-63 ------> bonito irq
126 */
127
128 /* Sets the first-level interrupt dispatcher. */
129 mips_cpu_irq_init();
130 init_i8259_irqs();
131 bonito_irq_init();
132
133 /*
134 printk("GPIODATA=%x, GPIOIE=%x\n", BONITO_GPIODATA, BONITO_GPIOIE);
135 printk("INTEN=%x, INTSET=%x, INTCLR=%x, INTISR=%x\n",
136 BONITO_INTEN, BONITO_INTENSET,
137 BONITO_INTENCLR, BONITO_INTISR);
138 */
139
140 /* bonito irq at IP2 */
141 setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
142 /* 8259 irq at IP5 */
143 setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction);
144
145}