aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorImre Deak <imre.deak@nokia.com>2006-06-26 19:16:00 -0400
committerTony Lindgren <tony@atomide.com>2006-06-26 19:16:00 -0400
commitea6dedd7fbd0f760ebf37eb0bcc8c64856475a13 (patch)
tree01d4dc723a6fa3fb567dc2d0ce497e69af4d7721 /arch
parent7876284178b386ab6e97f96733ccbc19eda743a3 (diff)
ARM: OMAP: GPIO IRQ lazy IRQ disable fix
- The current OMAP GPIO IRQ framework doesn't use the do_edge_IRQ, do_level_IRQ handlers, but instead calls do_simple_IRQ. This doesn't handle disabled interrupts properly, so drivers will still get interrupts after calling disable_irq. The patch solves this by respecting the irq_desc.disable_depth and irq_desc.running counters. When one of these is non-zero the handler is not called, the interrupt is masked and marked as pending. The pending interrupt will be serviced when the running handler returns. This is according to the same semantics as the standard do_edge_IRQ and do_level_IRQ handlers have, so one day we should use them instead of do_simple_IRQ. - Process only interrupts that are not masked. The ISR may contain pending interrupts that are masked these shouldn't be processed. - Move the bank IRQ unmasking out of the IRQ dispatch loop. If there are further iterations we shouldn't unmask it if there are level triggered interrupts pending. Signed-off-by: Imre Deak <imre.deak@nokia.com> Signed-off-by: Juha Yrjola <juha.yrjola@nokia.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/plat-omap/gpio.c88
1 files changed, 79 insertions, 9 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index d3c8ea7eecfd..cd1e508f90c1 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -537,6 +537,34 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
537 _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio)); 537 _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
538} 538}
539 539
540static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
541{
542 void __iomem *reg = bank->base;
543
544 switch (bank->method) {
545 case METHOD_MPUIO:
546 reg += OMAP_MPUIO_GPIO_MASKIT;
547 break;
548 case METHOD_GPIO_1510:
549 reg += OMAP1510_GPIO_INT_MASK;
550 break;
551 case METHOD_GPIO_1610:
552 reg += OMAP1610_GPIO_IRQENABLE1;
553 break;
554 case METHOD_GPIO_730:
555 reg += OMAP730_GPIO_INT_MASK;
556 break;
557 case METHOD_GPIO_24XX:
558 reg += OMAP24XX_GPIO_IRQENABLE1;
559 break;
560 default:
561 BUG();
562 return 0;
563 }
564
565 return __raw_readl(reg);
566}
567
540static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) 568static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
541{ 569{
542 void __iomem *reg = bank->base; 570 void __iomem *reg = bank->base;
@@ -736,6 +764,8 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
736 u32 isr; 764 u32 isr;
737 unsigned int gpio_irq; 765 unsigned int gpio_irq;
738 struct gpio_bank *bank; 766 struct gpio_bank *bank;
767 u32 retrigger = 0;
768 int unmasked = 0;
739 769
740 desc->chip->ack(irq); 770 desc->chip->ack(irq);
741 771
@@ -760,18 +790,22 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
760#endif 790#endif
761 while(1) { 791 while(1) {
762 u32 isr_saved, level_mask = 0; 792 u32 isr_saved, level_mask = 0;
793 u32 enabled;
763 794
764 isr_saved = isr = __raw_readl(isr_reg); 795 enabled = _get_gpio_irqbank_mask(bank);
796 isr_saved = isr = __raw_readl(isr_reg) & enabled;
765 797
766 if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO)) 798 if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
767 isr &= 0x0000ffff; 799 isr &= 0x0000ffff;
768 800
769 if (cpu_is_omap24xx()) 801 if (cpu_is_omap24xx()) {
770 level_mask = 802 level_mask =
771 __raw_readl(bank->base + 803 __raw_readl(bank->base +
772 OMAP24XX_GPIO_LEVELDETECT0) | 804 OMAP24XX_GPIO_LEVELDETECT0) |
773 __raw_readl(bank->base + 805 __raw_readl(bank->base +
774 OMAP24XX_GPIO_LEVELDETECT1); 806 OMAP24XX_GPIO_LEVELDETECT1);
807 level_mask &= enabled;
808 }
775 809
776 /* clear edge sensitive interrupts before handler(s) are 810 /* clear edge sensitive interrupts before handler(s) are
777 called so that we don't miss any interrupt occurred while 811 called so that we don't miss any interrupt occurred while
@@ -782,19 +816,54 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
782 816
783 /* if there is only edge sensitive GPIO pin interrupts 817 /* if there is only edge sensitive GPIO pin interrupts
784 configured, we could unmask GPIO bank interrupt immediately */ 818 configured, we could unmask GPIO bank interrupt immediately */
785 if (!level_mask) 819 if (!level_mask && !unmasked) {
820 unmasked = 1;
786 desc->chip->unmask(irq); 821 desc->chip->unmask(irq);
822 }
787 823
824 isr |= retrigger;
825 retrigger = 0;
788 if (!isr) 826 if (!isr)
789 break; 827 break;
790 828
791 gpio_irq = bank->virtual_irq_start; 829 gpio_irq = bank->virtual_irq_start;
792 for (; isr != 0; isr >>= 1, gpio_irq++) { 830 for (; isr != 0; isr >>= 1, gpio_irq++) {
793 struct irqdesc *d; 831 struct irqdesc *d;
832 int irq_mask;
794 if (!(isr & 1)) 833 if (!(isr & 1))
795 continue; 834 continue;
796 d = irq_desc + gpio_irq; 835 d = irq_desc + gpio_irq;
836 /* Don't run the handler if it's already running
837 * or was disabled lazely.
838 */
839 if (unlikely((d->disable_depth || d->running))) {
840 irq_mask = 1 <<
841 (gpio_irq - bank->virtual_irq_start);
842 /* The unmasking will be done by
843 * enable_irq in case it is disabled or
844 * after returning from the handler if
845 * it's already running.
846 */
847 _enable_gpio_irqbank(bank, irq_mask, 0);
848 if (!d->disable_depth) {
849 /* Level triggered interrupts
850 * won't ever be reentered
851 */
852 BUG_ON(level_mask & irq_mask);
853 d->pending = 1;
854 }
855 continue;
856 }
857 d->running = 1;
797 desc_handle_irq(gpio_irq, d, regs); 858 desc_handle_irq(gpio_irq, d, regs);
859 d->running = 0;
860 if (unlikely(d->pending && !d->disable_depth)) {
861 irq_mask = 1 <<
862 (gpio_irq - bank->virtual_irq_start);
863 d->pending = 0;
864 _enable_gpio_irqbank(bank, irq_mask, 1);
865 retrigger |= irq_mask;
866 }
798 } 867 }
799 868
800 if (cpu_is_omap24xx()) { 869 if (cpu_is_omap24xx()) {
@@ -804,13 +873,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
804 _enable_gpio_irqbank(bank, isr_saved & level_mask, 1); 873 _enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
805 } 874 }
806 875
807 /* if bank has any level sensitive GPIO pin interrupt
808 configured, we must unmask the bank interrupt only after
809 handler(s) are executed in order to avoid spurious bank
810 interrupt */
811 if (level_mask)
812 desc->chip->unmask(irq);
813 } 876 }
877 /* if bank has any level sensitive GPIO pin interrupt
878 configured, we must unmask the bank interrupt only after
879 handler(s) are executed in order to avoid spurious bank
880 interrupt */
881 if (!unmasked)
882 desc->chip->unmask(irq);
883
814} 884}
815 885
816static void gpio_ack_irq(unsigned int irq) 886static void gpio_ack_irq(unsigned int irq)