diff options
author | Mike Frysinger <vapier@gentoo.org> | 2011-04-15 12:51:33 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2011-05-25 08:13:43 -0400 |
commit | e2a8092c3fa9766248e9515252ae44e6df2d97a0 (patch) | |
tree | 99619c0acee0ad019c8551465a1e37b71a9ff27a | |
parent | dd8cb37b4e92c487fd10e7da96bab18d33de62da (diff) |
Blackfin: bf537: fix excessive gpio int demuxing
The search logic in the gpio demux walks all possible gpio blocks starting
at the specified pin. The trouble on bf537 parts when we demux the port
F and port G mask A interrupts is that we also demux port H mask A ints.
Most of the time this isn't an issue as people don't usually use port H,
but might as well avoid it when possible.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index a77f96f9be7c..ad28eb12003a 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -567,22 +567,41 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) | |||
567 | # define bfin_gpio_set_wake NULL | 567 | # define bfin_gpio_set_wake NULL |
568 | #endif | 568 | #endif |
569 | 569 | ||
570 | static void bfin_demux_gpio_block(unsigned int irq) | ||
571 | { | ||
572 | unsigned int gpio, mask; | ||
573 | |||
574 | gpio = irq_to_gpio(irq); | ||
575 | mask = get_gpiop_data(gpio) & get_gpiop_maska(gpio); | ||
576 | |||
577 | while (mask) { | ||
578 | if (mask & 1) | ||
579 | bfin_handle_irq(irq); | ||
580 | irq++; | ||
581 | mask >>= 1; | ||
582 | } | ||
583 | } | ||
584 | |||
570 | static void bfin_demux_gpio_irq(unsigned int inta_irq, | 585 | static void bfin_demux_gpio_irq(unsigned int inta_irq, |
571 | struct irq_desc *desc) | 586 | struct irq_desc *desc) |
572 | { | 587 | { |
573 | unsigned int i, gpio, mask, irq, search = 0; | 588 | unsigned int irq; |
574 | 589 | ||
575 | switch (inta_irq) { | 590 | switch (inta_irq) { |
576 | #if defined(CONFIG_BF53x) | 591 | #if defined(BF537_FAMILY) |
577 | case IRQ_PROG_INTA: | 592 | case IRQ_PROG_INTA: |
578 | irq = IRQ_PF0; | 593 | bfin_demux_gpio_block(IRQ_PF0); |
579 | search = 1; | 594 | irq = IRQ_PG0; |
580 | break; | 595 | break; |
581 | # if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) | 596 | # if !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) |
582 | case IRQ_MAC_RX: | 597 | case IRQ_MAC_RX: |
583 | irq = IRQ_PH0; | 598 | irq = IRQ_PH0; |
584 | break; | 599 | break; |
585 | # endif | 600 | # endif |
601 | #elif defined(BF533_FAMILY) | ||
602 | case IRQ_PROG_INTA: | ||
603 | irq = IRQ_PF0; | ||
604 | break; | ||
586 | #elif defined(BF538_FAMILY) | 605 | #elif defined(BF538_FAMILY) |
587 | case IRQ_PORTF_INTA: | 606 | case IRQ_PORTF_INTA: |
588 | irq = IRQ_PF0; | 607 | irq = IRQ_PF0; |
@@ -613,31 +632,7 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
613 | return; | 632 | return; |
614 | } | 633 | } |
615 | 634 | ||
616 | if (search) { | 635 | bfin_demux_gpio_block(irq); |
617 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
618 | irq += i; | ||
619 | |||
620 | mask = get_gpiop_data(i) & get_gpiop_maska(i); | ||
621 | |||
622 | while (mask) { | ||
623 | if (mask & 1) | ||
624 | bfin_handle_irq(irq); | ||
625 | irq++; | ||
626 | mask >>= 1; | ||
627 | } | ||
628 | } | ||
629 | } else { | ||
630 | gpio = irq_to_gpio(irq); | ||
631 | mask = get_gpiop_data(gpio) & get_gpiop_maska(gpio); | ||
632 | |||
633 | do { | ||
634 | if (mask & 1) | ||
635 | bfin_handle_irq(irq); | ||
636 | irq++; | ||
637 | mask >>= 1; | ||
638 | } while (mask); | ||
639 | } | ||
640 | |||
641 | } | 636 | } |
642 | 637 | ||
643 | #else /* CONFIG_BF54x */ | 638 | #else /* CONFIG_BF54x */ |