aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy
diff options
context:
space:
mode:
authorManuel Lauss <manuel.lauss@googlemail.com>2011-12-08 05:42:16 -0500
committerRalf Baechle <ralf@linux-mips.org>2011-12-08 05:42:16 -0500
commit894cc87e2e24eccaf9a33f2744d618567f51408c (patch)
tree066806087cda3e51559880f583a61669edb999db /arch/mips/alchemy
parentf267c882c73db2f8d77b10902450666044b16633 (diff)
MIPS: Alchemy: chain IRQ controllers to MIPS IRQ controller
IC and GPIC are now chain handlers of the traditional MIPS IRQ controller. Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2933/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/alchemy')
-rw-r--r--arch/mips/alchemy/common/gpioint.c26
-rw-r--r--arch/mips/alchemy/common/irq.c62
2 files changed, 39 insertions, 49 deletions
diff --git a/arch/mips/alchemy/common/gpioint.c b/arch/mips/alchemy/common/gpioint.c
index 5d7729a59908..daaaab09044a 100644
--- a/arch/mips/alchemy/common/gpioint.c
+++ b/arch/mips/alchemy/common/gpioint.c
@@ -349,6 +349,12 @@ static struct syscore_ops alchemy_gpic_pmops = {
349 .resume = alchemy_gpic_resume, 349 .resume = alchemy_gpic_resume,
350}; 350};
351 351
352static void alchemy_gpic_dispatch(unsigned int irq, struct irq_desc *d)
353{
354 int i = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_PRIENC);
355 generic_handle_irq(ALCHEMY_GPIC_INT_BASE + i);
356}
357
352static void __init alchemy_gpic_init_irq(const struct gpic_devint_data *dints) 358static void __init alchemy_gpic_init_irq(const struct gpic_devint_data *dints)
353{ 359{
354 int i; 360 int i;
@@ -383,7 +389,10 @@ static void __init alchemy_gpic_init_irq(const struct gpic_devint_data *dints)
383 dints++; 389 dints++;
384 } 390 }
385 391
386 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3); 392 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, alchemy_gpic_dispatch);
393 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, alchemy_gpic_dispatch);
394 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, alchemy_gpic_dispatch);
395 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, alchemy_gpic_dispatch);
387} 396}
388 397
389/**********************************************************************/ 398/**********************************************************************/
@@ -397,17 +406,8 @@ void __init arch_init_irq(void)
397 } 406 }
398} 407}
399 408
400#define CAUSEF_GPIC (CAUSEF_IP2 | CAUSEF_IP3 | CAUSEF_IP4 | CAUSEF_IP5) 409asmlinkage void plat_irq_dispatch(void)
401
402void plat_irq_dispatch(void)
403{ 410{
404 unsigned long i, c = read_c0_cause() & read_c0_status(); 411 unsigned long r = (read_c0_status() & read_c0_cause()) >> 8;
405 412 do_IRQ(MIPS_CPU_IRQ_BASE + __ffs(r & 0xff));
406 if (c & CAUSEF_IP7) /* c0 timer */
407 do_IRQ(MIPS_CPU_IRQ_BASE + 7);
408 else if (likely(c & CAUSEF_GPIC)) {
409 i = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_PRIENC);
410 do_IRQ(i + ALCHEMY_GPIC_INT_BASE);
411 } else
412 spurious_interrupt();
413} 413}
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index f206e24961c5..ee80a32f5ef9 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -459,41 +459,6 @@ static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
459 return ret; 459 return ret;
460} 460}
461 461
462asmlinkage void plat_irq_dispatch(void)
463{
464 unsigned int pending = read_c0_status() & read_c0_cause();
465 unsigned long s, off;
466
467 if (pending & CAUSEF_IP7) {
468 off = MIPS_CPU_IRQ_BASE + 7;
469 goto handle;
470 } else if (pending & CAUSEF_IP2) {
471 s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ0INT;
472 off = AU1000_INTC0_INT_BASE;
473 } else if (pending & CAUSEF_IP3) {
474 s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ1INT;
475 off = AU1000_INTC0_INT_BASE;
476 } else if (pending & CAUSEF_IP4) {
477 s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ0INT;
478 off = AU1000_INTC1_INT_BASE;
479 } else if (pending & CAUSEF_IP5) {
480 s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ1INT;
481 off = AU1000_INTC1_INT_BASE;
482 } else
483 goto spurious;
484
485 s = __raw_readl((void __iomem *)s);
486 if (unlikely(!s)) {
487spurious:
488 spurious_interrupt();
489 return;
490 }
491 off += __ffs(s);
492handle:
493 do_IRQ(off);
494}
495
496
497static inline void ic_init(void __iomem *base) 462static inline void ic_init(void __iomem *base)
498{ 463{
499 /* initialize interrupt controller to a safe state */ 464 /* initialize interrupt controller to a safe state */
@@ -562,6 +527,22 @@ static struct syscore_ops alchemy_ic_syscore_ops = {
562 .resume = alchemy_ic_resume, 527 .resume = alchemy_ic_resume,
563}; 528};
564 529
530/* create chained handlers for the 4 IC requests to the MIPS IRQ ctrl */
531#define DISP(name, base, addr) \
532static void au1000_##name##_dispatch(unsigned int irq, struct irq_desc *d) \
533{ \
534 unsigned long r = __raw_readl((void __iomem *)KSEG1ADDR(addr)); \
535 if (likely(r)) \
536 generic_handle_irq(base + __ffs(r)); \
537 else \
538 spurious_interrupt(); \
539}
540
541DISP(ic0r0, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ0INT)
542DISP(ic0r1, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ1INT)
543DISP(ic1r0, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ0INT)
544DISP(ic1r1, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ1INT)
545
565static void __init au1000_init_irq(struct au1xxx_irqmap *map) 546static void __init au1000_init_irq(struct au1xxx_irqmap *map)
566{ 547{
567 unsigned int bit, irq_nr; 548 unsigned int bit, irq_nr;
@@ -603,7 +584,10 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
603 ++map; 584 ++map;
604 } 585 }
605 586
606 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3); 587 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, au1000_ic0r0_dispatch);
588 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, au1000_ic0r1_dispatch);
589 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, au1000_ic1r0_dispatch);
590 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, au1000_ic1r1_dispatch);
607} 591}
608 592
609void __init arch_init_irq(void) 593void __init arch_init_irq(void)
@@ -626,3 +610,9 @@ void __init arch_init_irq(void)
626 break; 610 break;
627 } 611 }
628} 612}
613
614asmlinkage void plat_irq_dispatch(void)
615{
616 unsigned long r = (read_c0_status() & read_c0_cause()) >> 8;
617 do_IRQ(MIPS_CPU_IRQ_BASE + __ffs(r & 0xff));
618}