diff options
Diffstat (limited to 'arch/mips/alchemy/common/irq.c')
-rw-r--r-- | arch/mips/alchemy/common/irq.c | 62 |
1 files changed, 26 insertions, 36 deletions
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index f206e24961c..ee80a32f5ef 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 | ||
462 | asmlinkage 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)) { | ||
487 | spurious: | ||
488 | spurious_interrupt(); | ||
489 | return; | ||
490 | } | ||
491 | off += __ffs(s); | ||
492 | handle: | ||
493 | do_IRQ(off); | ||
494 | } | ||
495 | |||
496 | |||
497 | static inline void ic_init(void __iomem *base) | 462 | static 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) \ | ||
532 | static 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 | |||
541 | DISP(ic0r0, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ0INT) | ||
542 | DISP(ic0r1, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ1INT) | ||
543 | DISP(ic1r0, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ0INT) | ||
544 | DISP(ic1r1, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ1INT) | ||
545 | |||
565 | static void __init au1000_init_irq(struct au1xxx_irqmap *map) | 546 | static 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 | ||
609 | void __init arch_init_irq(void) | 593 | void __init arch_init_irq(void) |
@@ -626,3 +610,9 @@ void __init arch_init_irq(void) | |||
626 | break; | 610 | break; |
627 | } | 611 | } |
628 | } | 612 | } |
613 | |||
614 | asmlinkage 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 | } | ||