diff options
Diffstat (limited to 'drivers/gpio/gpio-omap.c')
| -rw-r--r-- | drivers/gpio/gpio-omap.c | 24 | 
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)  	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))  		irq_set_handler_locked(d, handle_level_irq);  	else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) -		irq_set_handler_locked(d, handle_edge_irq); +		/* +		 * Edge IRQs are already cleared/acked in irq_handler and +		 * not need to be masked, as result handle_edge_irq() +		 * logic is excessed here and may cause lose of interrupts. +		 * So just use handle_simple_irq. +		 */ +		irq_set_handler_locked(d, handle_simple_irq);  	return 0; @@ -678,7 +684,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)  static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)  {  	void __iomem *isr_reg = NULL; -	u32 isr; +	u32 enabled, isr, level_mask;  	unsigned int bit;  	struct gpio_bank *bank = gpiobank;  	unsigned long wa_lock_flags; @@ -691,23 +697,21 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)  	pm_runtime_get_sync(bank->chip.parent);  	while (1) { -		u32 isr_saved, level_mask = 0; -		u32 enabled; -  		raw_spin_lock_irqsave(&bank->lock, lock_flags);  		enabled = omap_get_gpio_irqbank_mask(bank); -		isr_saved = isr = readl_relaxed(isr_reg) & enabled; +		isr = readl_relaxed(isr_reg) & enabled;  		if (bank->level_mask)  			level_mask = bank->level_mask & enabled; +		else +			level_mask = 0;  		/* clear edge sensitive interrupts before handler(s) are  		called so that we don't miss any interrupt occurred while  		executing them */ -		omap_disable_gpio_irqbank(bank, isr_saved & ~level_mask); -		omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask); -		omap_enable_gpio_irqbank(bank, isr_saved & ~level_mask); +		if (isr & ~level_mask) +			omap_clear_gpio_irqbank(bank, isr & ~level_mask);  		raw_spin_unlock_irqrestore(&bank->lock, lock_flags); @@ -1010,7 +1014,7 @@ static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value)  /*---------------------------------------------------------------------*/ -static void __init omap_gpio_show_rev(struct gpio_bank *bank) +static void omap_gpio_show_rev(struct gpio_bank *bank)  {  	static bool called;  	u32 rev; | 
