blob: 3e0b7beb1009b336c0eee30f2da22428d6196db2 [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>
Songmao Tian42d226c2007-06-06 14:52:38 +080028#include <linux/init.h>
29#include <linux/interrupt.h>
30#include <linux/irq.h>
31
32#include <asm/irq_cpu.h>
33#include <asm/i8259.h>
34#include <asm/mipsregs.h>
35#include <asm/mips-boards/bonito64.h>
36
37
38/*
39 * the first level int-handler will jump here if it is a bonito irq
40 */
41static void bonito_irqdispatch(void)
42{
43 u32 int_status;
44 int i;
45
46 /* workaround the IO dma problem: let cpu looping to allow DMA finish */
47 int_status = BONITO_INTISR;
48 if (int_status & (1 << 10)) {
49 while (int_status & (1 << 10)) {
50 udelay(1);
51 int_status = BONITO_INTISR;
52 }
53 }
54
55 /* Get pending sources, masked by current enables */
56 int_status = BONITO_INTISR & BONITO_INTEN;
57
58 if (int_status != 0) {
59 i = __ffs(int_status);
60 int_status &= ~(1 << i);
61 do_IRQ(BONITO_IRQ_BASE + i);
62 }
63}
64
65static void i8259_irqdispatch(void)
66{
67 int irq;
68
69 irq = i8259_irq();
70 if (irq >= 0) {
71 do_IRQ(irq);
72 } else {
73 spurious_interrupt();
74 }
75
76}
77
78asmlinkage void plat_irq_dispatch(void)
79{
80 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
81
82 if (pending & CAUSEF_IP7) {
83 do_IRQ(MIPS_CPU_IRQ_BASE + 7);
84 } else if (pending & CAUSEF_IP5) {
85 i8259_irqdispatch();
86 } else if (pending & CAUSEF_IP2) {
87 bonito_irqdispatch();
88 } else {
89 spurious_interrupt();
90 }
91}
92
93static struct irqaction cascade_irqaction = {
94 .handler = no_action,
95 .mask = CPU_MASK_NONE,
96 .name = "cascade",
97};
98
99void __init arch_init_irq(void)
100{
101 extern void bonito_irq_init(void);
102
103 /*
104 * Clear all of the interrupts while we change the able around a bit.
105 * int-handler is not on bootstrap
106 */
107 clear_c0_status(ST0_IM | ST0_BEV);
108 local_irq_disable();
109
110 /* most bonito irq should be level triggered */
111 BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
112 BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
113 BONITO_INTSTEER = 0;
114
115 /*
116 * Mask out all interrupt by writing "1" to all bit position in
117 * the interrupt reset reg.
118 */
119 BONITO_INTENCLR = ~0;
120
121 /* init all controller
122 * 0-15 ------> i8259 interrupt
123 * 16-23 ------> mips cpu interrupt
124 * 32-63 ------> bonito irq
125 */
126
127 /* Sets the first-level interrupt dispatcher. */
128 mips_cpu_irq_init();
129 init_i8259_irqs();
130 bonito_irq_init();
131
132 /*
133 printk("GPIODATA=%x, GPIOIE=%x\n", BONITO_GPIODATA, BONITO_GPIOIE);
134 printk("INTEN=%x, INTSET=%x, INTCLR=%x, INTISR=%x\n",
135 BONITO_INTEN, BONITO_INTENSET,
136 BONITO_INTENCLR, BONITO_INTISR);
137 */
138
139 /* bonito irq at IP2 */
140 setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
141 /* 8259 irq at IP5 */
142 setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction);
143
144}