Skip to content

Commit

Permalink
pinctrl: bcm2835: Clear the event latch register when disabling inter…
Browse files Browse the repository at this point in the history
…rupts

It's possible to hit a race condition if interrupts are generated on a GPIO
pin when the IRQ line in question is being disabled.

If the interrupt is freed, bcm2835_gpio_irq_disable() is called which
disables the event generation sources (edge, level). If an event occurred
between the last disabling of hard IRQs and the write to the event
source registers, a bit would be set in the GPIO event detect register
(GPEDSn) which goes unacknowledged by bcm2835_gpio_irq_handler()
so Linux complains loudly.

There is no per-GPIO mask register, so when disabling GPIO interrupts
write 1 to the relevant bit in GPEDSn to clear out any stale events.

Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
Jonathan Bell authored and Linus Walleij committed Jul 20, 2015
1 parent c10372e commit 714b1dd
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/pinctrl/bcm/pinctrl-bcm2835.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ static void bcm2835_gpio_irq_disable(struct irq_data *data)

spin_lock_irqsave(&pc->irq_lock[bank], flags);
bcm2835_gpio_irq_config(pc, gpio, false);
/* Clear events that were latched prior to clearing event sources */
bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
clear_bit(offset, &pc->enabled_irq_map[bank]);
spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
}
Expand Down

0 comments on commit 714b1dd

Please sign in to comment.