aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-omap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-omap.c')
-rw-r--r--drivers/gpio/gpio-omap.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index dbf869fb63ce..3233b72b6828 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -518,7 +518,13 @@ static int omap_gpio_irq_type(struct irq_data *d, unsigned type)
518 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) 518 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
519 irq_set_handler_locked(d, handle_level_irq); 519 irq_set_handler_locked(d, handle_level_irq);
520 else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) 520 else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
521 irq_set_handler_locked(d, handle_edge_irq); 521 /*
522 * Edge IRQs are already cleared/acked in irq_handler and
523 * not need to be masked, as result handle_edge_irq()
524 * logic is excessed here and may cause lose of interrupts.
525 * So just use handle_simple_irq.
526 */
527 irq_set_handler_locked(d, handle_simple_irq);
522 528
523 return 0; 529 return 0;
524 530
@@ -678,7 +684,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
678static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) 684static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
679{ 685{
680 void __iomem *isr_reg = NULL; 686 void __iomem *isr_reg = NULL;
681 u32 isr; 687 u32 enabled, isr, level_mask;
682 unsigned int bit; 688 unsigned int bit;
683 struct gpio_bank *bank = gpiobank; 689 struct gpio_bank *bank = gpiobank;
684 unsigned long wa_lock_flags; 690 unsigned long wa_lock_flags;
@@ -691,23 +697,21 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
691 pm_runtime_get_sync(bank->chip.parent); 697 pm_runtime_get_sync(bank->chip.parent);
692 698
693 while (1) { 699 while (1) {
694 u32 isr_saved, level_mask = 0;
695 u32 enabled;
696
697 raw_spin_lock_irqsave(&bank->lock, lock_flags); 700 raw_spin_lock_irqsave(&bank->lock, lock_flags);
698 701
699 enabled = omap_get_gpio_irqbank_mask(bank); 702 enabled = omap_get_gpio_irqbank_mask(bank);
700 isr_saved = isr = readl_relaxed(isr_reg) & enabled; 703 isr = readl_relaxed(isr_reg) & enabled;
701 704
702 if (bank->level_mask) 705 if (bank->level_mask)
703 level_mask = bank->level_mask & enabled; 706 level_mask = bank->level_mask & enabled;
707 else
708 level_mask = 0;
704 709
705 /* clear edge sensitive interrupts before handler(s) are 710 /* clear edge sensitive interrupts before handler(s) are
706 called so that we don't miss any interrupt occurred while 711 called so that we don't miss any interrupt occurred while
707 executing them */ 712 executing them */
708 omap_disable_gpio_irqbank(bank, isr_saved & ~level_mask); 713 if (isr & ~level_mask)
709 omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask); 714 omap_clear_gpio_irqbank(bank, isr & ~level_mask);
710 omap_enable_gpio_irqbank(bank, isr_saved & ~level_mask);
711 715
712 raw_spin_unlock_irqrestore(&bank->lock, lock_flags); 716 raw_spin_unlock_irqrestore(&bank->lock, lock_flags);
713 717
@@ -1010,7 +1014,7 @@ static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
1010 1014
1011/*---------------------------------------------------------------------*/ 1015/*---------------------------------------------------------------------*/
1012 1016
1013static void __init omap_gpio_show_rev(struct gpio_bank *bank) 1017static void omap_gpio_show_rev(struct gpio_bank *bank)
1014{ 1018{
1015 static bool called; 1019 static bool called;
1016 u32 rev; 1020 u32 rev;