aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/lantiq/irq.c68
1 files changed, 5 insertions, 63 deletions
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index f0bc3312ed11..c4ef1c31e0c4 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -224,9 +224,11 @@ static struct irq_chip ltq_eiu_type = {
224 .irq_set_type = ltq_eiu_settype, 224 .irq_set_type = ltq_eiu_settype,
225}; 225};
226 226
227static void ltq_hw_irqdispatch(int module) 227static void ltq_hw_irq_handler(struct irq_desc *desc)
228{ 228{
229 int module = irq_desc_get_irq(desc) - 2;
229 u32 irq; 230 u32 irq;
231 int hwirq;
230 232
231 irq = ltq_icu_r32(module, LTQ_ICU_IM0_IOSR); 233 irq = ltq_icu_r32(module, LTQ_ICU_IM0_IOSR);
232 if (irq == 0) 234 if (irq == 0)
@@ -237,7 +239,8 @@ static void ltq_hw_irqdispatch(int module)
237 * other bits might be bogus 239 * other bits might be bogus
238 */ 240 */
239 irq = __fls(irq); 241 irq = __fls(irq);
240 do_IRQ((int)irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module)); 242 hwirq = irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module);
243 generic_handle_irq(irq_linear_revmap(ltq_domain, hwirq));
241 244
242 /* if this is a EBU irq, we need to ack it or get a deadlock */ 245 /* if this is a EBU irq, we need to ack it or get a deadlock */
243 if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT) 246 if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT)
@@ -245,49 +248,6 @@ static void ltq_hw_irqdispatch(int module)
245 LTQ_EBU_PCC_ISTAT); 248 LTQ_EBU_PCC_ISTAT);
246} 249}
247 250
248#define DEFINE_HWx_IRQDISPATCH(x) \
249 static void ltq_hw ## x ## _irqdispatch(void) \
250 { \
251 ltq_hw_irqdispatch(x); \
252 }
253DEFINE_HWx_IRQDISPATCH(0)
254DEFINE_HWx_IRQDISPATCH(1)
255DEFINE_HWx_IRQDISPATCH(2)
256DEFINE_HWx_IRQDISPATCH(3)
257DEFINE_HWx_IRQDISPATCH(4)
258
259#if MIPS_CPU_TIMER_IRQ == 7
260static void ltq_hw5_irqdispatch(void)
261{
262 do_IRQ(MIPS_CPU_TIMER_IRQ);
263}
264#else
265DEFINE_HWx_IRQDISPATCH(5)
266#endif
267
268static void ltq_hw_irq_handler(struct irq_desc *desc)
269{
270 ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2);
271}
272
273asmlinkage void plat_irq_dispatch(void)
274{
275 unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
276 int irq;
277
278 if (!pending) {
279 spurious_interrupt();
280 return;
281 }
282
283 pending >>= CAUSEB_IP;
284 while (pending) {
285 irq = fls(pending) - 1;
286 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
287 pending &= ~BIT(irq);
288 }
289}
290
291static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) 251static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
292{ 252{
293 struct irq_chip *chip = &ltq_irq_type; 253 struct irq_chip *chip = &ltq_irq_type;
@@ -343,28 +303,10 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
343 for (i = 0; i < MAX_IM; i++) 303 for (i = 0; i < MAX_IM; i++)
344 irq_set_chained_handler(i + 2, ltq_hw_irq_handler); 304 irq_set_chained_handler(i + 2, ltq_hw_irq_handler);
345 305
346 if (cpu_has_vint) {
347 pr_info("Setting up vectored interrupts\n");
348 set_vi_handler(2, ltq_hw0_irqdispatch);
349 set_vi_handler(3, ltq_hw1_irqdispatch);
350 set_vi_handler(4, ltq_hw2_irqdispatch);
351 set_vi_handler(5, ltq_hw3_irqdispatch);
352 set_vi_handler(6, ltq_hw4_irqdispatch);
353 set_vi_handler(7, ltq_hw5_irqdispatch);
354 }
355
356 ltq_domain = irq_domain_add_linear(node, 306 ltq_domain = irq_domain_add_linear(node,
357 (MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE, 307 (MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE,
358 &irq_domain_ops, 0); 308 &irq_domain_ops, 0);
359 309
360#ifndef CONFIG_MIPS_MT_SMP
361 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
362 IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
363#else
364 set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
365 IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
366#endif
367
368 /* tell oprofile which irq to use */ 310 /* tell oprofile which irq to use */
369 ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); 311 ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ);
370 312