aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mips-boards/malta/malta_int.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-07-14 11:57:16 -0400
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:31:53 -0400
commite01402b115cccb6357f956649487aca2c6f7fbba (patch)
tree256e14f8d2762de98b992219b1a47e8f56b4b0da /arch/mips/mips-boards/malta/malta_int.c
parent86071b637db7baf599df26fdf820dce2fc55ca9f (diff)
More AP / SP bits for the 34K, the Malta bits and things. Still wants
a little polishing. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mips-boards/malta/malta_int.c')
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c136
1 files changed, 105 insertions, 31 deletions
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
index dd2db35966bc..6f99a4492015 100644
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -30,6 +30,7 @@
30#include <linux/random.h> 30#include <linux/random.h>
31 31
32#include <asm/i8259.h> 32#include <asm/i8259.h>
33#include <asm/irq_cpu.h>
33#include <asm/io.h> 34#include <asm/io.h>
34#include <asm/mips-boards/malta.h> 35#include <asm/mips-boards/malta.h>
35#include <asm/mips-boards/maltaint.h> 36#include <asm/mips-boards/maltaint.h>
@@ -37,8 +38,10 @@
37#include <asm/gt64120.h> 38#include <asm/gt64120.h>
38#include <asm/mips-boards/generic.h> 39#include <asm/mips-boards/generic.h>
39#include <asm/mips-boards/msc01_pci.h> 40#include <asm/mips-boards/msc01_pci.h>
41#include <asm/msc01_ic.h>
40 42
41extern asmlinkage void mipsIRQ(void); 43extern asmlinkage void mipsIRQ(void);
44extern void mips_timer_interrupt(void);
42 45
43static DEFINE_SPINLOCK(mips_irq_lock); 46static DEFINE_SPINLOCK(mips_irq_lock);
44 47
@@ -91,13 +94,13 @@ static inline int mips_pcibios_iack(void)
91 return irq; 94 return irq;
92} 95}
93 96
94static inline int get_int(int *irq) 97static inline int get_int(void)
95{ 98{
96 unsigned long flags; 99 unsigned long flags;
97 100 int irq;
98 spin_lock_irqsave(&mips_irq_lock, flags); 101 spin_lock_irqsave(&mips_irq_lock, flags);
99 102
100 *irq = mips_pcibios_iack(); 103 irq = mips_pcibios_iack();
101 104
102 /* 105 /*
103 * IRQ7 is used to detect spurious interrupts. 106 * IRQ7 is used to detect spurious interrupts.
@@ -106,73 +109,82 @@ static inline int get_int(int *irq)
106 * We can differentiate between this situation and a 109 * We can differentiate between this situation and a
107 * "Normal" IRQ7 by reading the ISR. 110 * "Normal" IRQ7 by reading the ISR.
108 */ 111 */
109 if (*irq == 7) 112 if (irq == 7)
110 { 113 {
111 outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, 114 outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR,
112 PIIX4_ICTLR1_OCW3); 115 PIIX4_ICTLR1_OCW3);
113 if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) { 116 if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) {
114 spin_unlock_irqrestore(&mips_irq_lock, flags); 117 irq = -1; /* Spurious interrupt */
115 printk("We got a spurious interrupt from PIIX4.\n"); 118 printk("We got a spurious interrupt from PIIX4.\n");
116 atomic_inc(&irq_err_count); 119 atomic_inc(&irq_err_count);
117 return -1; /* Spurious interrupt. */
118 } 120 }
119 } 121 }
120 122
121 spin_unlock_irqrestore(&mips_irq_lock, flags); 123 spin_unlock_irqrestore(&mips_irq_lock, flags);
122 124
123 return 0; 125 return irq;
124} 126}
125 127
126void malta_hw0_irqdispatch(struct pt_regs *regs) 128void malta_hw0_irqdispatch(struct pt_regs *regs)
127{ 129{
128 int irq; 130 int irq;
129 131
130 if (get_int(&irq)) 132 irq = get_int();
131 return; /* interrupt has already been cleared */ 133 if (irq < 0)
134 return; /* interrupt has already been cleared */
132 135
133 do_IRQ(irq, regs); 136 do_IRQ(MALTA_INT_BASE+irq, regs);
134} 137}
135 138
136void corehi_irqdispatch(struct pt_regs *regs) 139void corehi_irqdispatch(struct pt_regs *regs)
137{ 140{
138 unsigned int data,datahi; 141 unsigned int intrcause,datalo,datahi;
139 142 unsigned int pcimstat, intisr, inten, intpol, intedge, intsteer, pcicmd, pcibadaddr;
140 /* Mask out corehi interrupt. */
141 clear_c0_status(IE_IRQ3);
142 143
143 printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); 144 printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n");
144 printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n" 145 printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n"
145, regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr); 146, regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr);
147
148 /* Read all the registers and then print them as there is a
149 problem with interspersed printk's upsetting the Bonito controller.
150 Do it for the others too.
151 */
152
146 switch(mips_revision_corid) { 153 switch(mips_revision_corid) {
147 case MIPS_REVISION_CORID_CORE_MSC: 154 case MIPS_REVISION_CORID_CORE_MSC:
148 case MIPS_REVISION_CORID_CORE_FPGA2: 155 case MIPS_REVISION_CORID_CORE_FPGA2:
149 case MIPS_REVISION_CORID_CORE_EMUL_MSC: 156 case MIPS_REVISION_CORID_CORE_EMUL_MSC:
157 ll_msc_irq(regs);
150 break; 158 break;
151 case MIPS_REVISION_CORID_QED_RM5261: 159 case MIPS_REVISION_CORID_QED_RM5261:
152 case MIPS_REVISION_CORID_CORE_LV: 160 case MIPS_REVISION_CORID_CORE_LV:
153 case MIPS_REVISION_CORID_CORE_FPGA: 161 case MIPS_REVISION_CORID_CORE_FPGA:
154 case MIPS_REVISION_CORID_CORE_FPGAR2: 162 case MIPS_REVISION_CORID_CORE_FPGAR2:
155 data = GT_READ(GT_INTRCAUSE_OFS); 163 intrcause = GT_READ(GT_INTRCAUSE_OFS);
156 printk("GT_INTRCAUSE = %08x\n", data); 164 datalo = GT_READ(GT_CPUERR_ADDRLO_OFS);
157 data = GT_READ(GT_CPUERR_ADDRLO_OFS);
158 datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); 165 datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
159 printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data); 166 printk("GT_INTRCAUSE = %08x\n", intrcause);
167 printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo);
160 break; 168 break;
161 case MIPS_REVISION_CORID_BONITO64: 169 case MIPS_REVISION_CORID_BONITO64:
162 case MIPS_REVISION_CORID_CORE_20K: 170 case MIPS_REVISION_CORID_CORE_20K:
163 case MIPS_REVISION_CORID_CORE_EMUL_BON: 171 case MIPS_REVISION_CORID_CORE_EMUL_BON:
164 data = BONITO_INTISR; 172 pcibadaddr = BONITO_PCIBADADDR;
165 printk("BONITO_INTISR = %08x\n", data); 173 pcimstat = BONITO_PCIMSTAT;
166 data = BONITO_INTEN; 174 intisr = BONITO_INTISR;
167 printk("BONITO_INTEN = %08x\n", data); 175 inten = BONITO_INTEN;
168 data = BONITO_INTPOL; 176 intpol = BONITO_INTPOL;
169 printk("BONITO_INTPOL = %08x\n", data); 177 intedge = BONITO_INTEDGE;
170 data = BONITO_INTEDGE; 178 intsteer = BONITO_INTSTEER;
171 printk("BONITO_INTEDGE = %08x\n", data); 179 pcicmd = BONITO_PCICMD;
172 data = BONITO_INTSTEER; 180 printk("BONITO_INTISR = %08x\n", intisr);
173 printk("BONITO_INTSTEER = %08x\n", data); 181 printk("BONITO_INTEN = %08x\n", inten);
174 data = BONITO_PCICMD; 182 printk("BONITO_INTPOL = %08x\n", intpol);
175 printk("BONITO_PCICMD = %08x\n", data); 183 printk("BONITO_INTEDGE = %08x\n", intedge);
184 printk("BONITO_INTSTEER = %08x\n", intsteer);
185 printk("BONITO_PCICMD = %08x\n", pcicmd);
186 printk("BONITO_PCIBADADDR = %08x\n", pcibadaddr);
187 printk("BONITO_PCIMSTAT = %08x\n", pcimstat);
176 break; 188 break;
177 } 189 }
178 190
@@ -180,8 +192,70 @@ void corehi_irqdispatch(struct pt_regs *regs)
180 die("CoreHi interrupt", regs); 192 die("CoreHi interrupt", regs);
181} 193}
182 194
195static struct irqaction i8259irq = {
196 .handler = no_action,
197 .name = "XT-PIC cascade"
198};
199
200static struct irqaction corehi_irqaction = {
201 .handler = no_action,
202 .name = "CoreHi"
203};
204
205msc_irqmap_t __initdata msc_irqmap[] = {
206 {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0},
207 {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0},
208};
209int __initdata msc_nr_irqs = sizeof(msc_irqmap)/sizeof(msc_irqmap_t);
210
211msc_irqmap_t __initdata msc_eicirqmap[] = {
212 {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0},
213 {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0},
214 {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0},
215 {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0},
216 {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0},
217 {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0},
218 {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0},
219 {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0},
220 {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0},
221 {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0}
222};
223int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t);
224
183void __init arch_init_irq(void) 225void __init arch_init_irq(void)
184{ 226{
185 set_except_vector(0, mipsIRQ); 227 set_except_vector(0, mipsIRQ);
186 init_i8259_irqs(); 228 init_i8259_irqs();
229
230 if (!cpu_has_veic)
231 mips_cpu_irq_init (MIPSCPU_INT_BASE);
232
233 switch(mips_revision_corid) {
234 case MIPS_REVISION_CORID_CORE_MSC:
235 case MIPS_REVISION_CORID_CORE_FPGA2:
236 case MIPS_REVISION_CORID_CORE_EMUL_MSC:
237 if (cpu_has_veic)
238 init_msc_irqs (MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs);
239 else
240 init_msc_irqs (MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs);
241 }
242
243 if (cpu_has_veic) {
244 set_vi_handler (MSC01E_INT_I8259A, malta_hw0_irqdispatch);
245 set_vi_handler (MSC01E_INT_COREHI, corehi_irqdispatch);
246 setup_irq (MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq);
247 setup_irq (MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction);
248 }
249 else if (cpu_has_vint) {
250 set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
251 set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch);
252
253 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
254 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
255 }
256 else {
257 set_except_vector(0, mipsIRQ);
258 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
259 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
260 }
187} 261}