diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2011-12-08 05:42:16 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-12-08 05:42:16 -0500 |
commit | 894cc87e2e24eccaf9a33f2744d618567f51408c (patch) | |
tree | 066806087cda3e51559880f583a61669edb999db /arch/mips/alchemy | |
parent | f267c882c73db2f8d77b10902450666044b16633 (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.c | 26 | ||||
-rw-r--r-- | arch/mips/alchemy/common/irq.c | 62 |
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 | ||
352 | static 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 | |||
352 | static void __init alchemy_gpic_init_irq(const struct gpic_devint_data *dints) | 358 | static 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) | 409 | asmlinkage void plat_irq_dispatch(void) |
401 | |||
402 | void 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 | ||
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 | } | ||