aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/gpio.c')
-rw-r--r--arch/arm/plat-omap/gpio.c103
1 files changed, 94 insertions, 9 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index d3c8ea7eecfd..e75a2ca70ba1 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -537,6 +537,49 @@ 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 int inv = 0;
544 u32 l;
545 u32 mask;
546
547 switch (bank->method) {
548 case METHOD_MPUIO:
549 reg += OMAP_MPUIO_GPIO_MASKIT;
550 mask = 0xffff;
551 inv = 1;
552 break;
553 case METHOD_GPIO_1510:
554 reg += OMAP1510_GPIO_INT_MASK;
555 mask = 0xffff;
556 inv = 1;
557 break;
558 case METHOD_GPIO_1610:
559 reg += OMAP1610_GPIO_IRQENABLE1;
560 mask = 0xffff;
561 break;
562 case METHOD_GPIO_730:
563 reg += OMAP730_GPIO_INT_MASK;
564 mask = 0xffffffff;
565 inv = 1;
566 break;
567 case METHOD_GPIO_24XX:
568 reg += OMAP24XX_GPIO_IRQENABLE1;
569 mask = 0xffffffff;
570 break;
571 default:
572 BUG();
573 return 0;
574 }
575
576 l = __raw_readl(reg);
577 if (inv)
578 l = ~l;
579 l &= mask;
580 return l;
581}
582
540static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) 583static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
541{ 584{
542 void __iomem *reg = bank->base; 585 void __iomem *reg = bank->base;
@@ -736,6 +779,8 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
736 u32 isr; 779 u32 isr;
737 unsigned int gpio_irq; 780 unsigned int gpio_irq;
738 struct gpio_bank *bank; 781 struct gpio_bank *bank;
782 u32 retrigger = 0;
783 int unmasked = 0;
739 784
740 desc->chip->ack(irq); 785 desc->chip->ack(irq);
741 786
@@ -760,18 +805,22 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
760#endif 805#endif
761 while(1) { 806 while(1) {
762 u32 isr_saved, level_mask = 0; 807 u32 isr_saved, level_mask = 0;
808 u32 enabled;
763 809
764 isr_saved = isr = __raw_readl(isr_reg); 810 enabled = _get_gpio_irqbank_mask(bank);
811 isr_saved = isr = __raw_readl(isr_reg) & enabled;
765 812
766 if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO)) 813 if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
767 isr &= 0x0000ffff; 814 isr &= 0x0000ffff;
768 815
769 if (cpu_is_omap24xx()) 816 if (cpu_is_omap24xx()) {
770 level_mask = 817 level_mask =
771 __raw_readl(bank->base + 818 __raw_readl(bank->base +
772 OMAP24XX_GPIO_LEVELDETECT0) | 819 OMAP24XX_GPIO_LEVELDETECT0) |
773 __raw_readl(bank->base + 820 __raw_readl(bank->base +
774 OMAP24XX_GPIO_LEVELDETECT1); 821 OMAP24XX_GPIO_LEVELDETECT1);
822 level_mask &= enabled;
823 }
775 824
776 /* clear edge sensitive interrupts before handler(s) are 825 /* clear edge sensitive interrupts before handler(s) are
777 called so that we don't miss any interrupt occurred while 826 called so that we don't miss any interrupt occurred while
@@ -782,19 +831,54 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
782 831
783 /* if there is only edge sensitive GPIO pin interrupts 832 /* if there is only edge sensitive GPIO pin interrupts
784 configured, we could unmask GPIO bank interrupt immediately */ 833 configured, we could unmask GPIO bank interrupt immediately */
785 if (!level_mask) 834 if (!level_mask && !unmasked) {
835 unmasked = 1;
786 desc->chip->unmask(irq); 836 desc->chip->unmask(irq);
837 }
787 838
839 isr |= retrigger;
840 retrigger = 0;
788 if (!isr) 841 if (!isr)
789 break; 842 break;
790 843
791 gpio_irq = bank->virtual_irq_start; 844 gpio_irq = bank->virtual_irq_start;
792 for (; isr != 0; isr >>= 1, gpio_irq++) { 845 for (; isr != 0; isr >>= 1, gpio_irq++) {
793 struct irqdesc *d; 846 struct irqdesc *d;
847 int irq_mask;
794 if (!(isr & 1)) 848 if (!(isr & 1))
795 continue; 849 continue;
796 d = irq_desc + gpio_irq; 850 d = irq_desc + gpio_irq;
851 /* Don't run the handler if it's already running
852 * or was disabled lazely.
853 */
854 if (unlikely((d->disable_depth || d->running))) {
855 irq_mask = 1 <<
856 (gpio_irq - bank->virtual_irq_start);
857 /* The unmasking will be done by
858 * enable_irq in case it is disabled or
859 * after returning from the handler if
860 * it's already running.
861 */
862 _enable_gpio_irqbank(bank, irq_mask, 0);
863 if (!d->disable_depth) {
864 /* Level triggered interrupts
865 * won't ever be reentered
866 */
867 BUG_ON(level_mask & irq_mask);
868 d->pending = 1;
869 }
870 continue;
871 }
872 d->running = 1;
797 desc_handle_irq(gpio_irq, d, regs); 873 desc_handle_irq(gpio_irq, d, regs);
874 d->running = 0;
875 if (unlikely(d->pending && !d->disable_depth)) {
876 irq_mask = 1 <<
877 (gpio_irq - bank->virtual_irq_start);
878 d->pending = 0;
879 _enable_gpio_irqbank(bank, irq_mask, 1);
880 retrigger |= irq_mask;
881 }
798 } 882 }
799 883
800 if (cpu_is_omap24xx()) { 884 if (cpu_is_omap24xx()) {
@@ -804,13 +888,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
804 _enable_gpio_irqbank(bank, isr_saved & level_mask, 1); 888 _enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
805 } 889 }
806 890
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 } 891 }
892 /* if bank has any level sensitive GPIO pin interrupt
893 configured, we must unmask the bank interrupt only after
894 handler(s) are executed in order to avoid spurious bank
895 interrupt */
896 if (!unmasked)
897 desc->chip->unmask(irq);
898
814} 899}
815 900
816static void gpio_ack_irq(unsigned int irq) 901static void gpio_ack_irq(unsigned int irq)