Message ID | 55927F0B.80602@raspberrypi.org |
---|---|
State | New |
Headers | show |
On 06/30/2015 05:35 AM, Jonathan Bell wrote: > 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. Acked-by: Stephen Warren <swarren@wwwdotorg.org> (Sorry for the slow response; I was on vacation) -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Jun 30, 2015 at 1:35 PM, Jonathan Bell <jonathan@raspberrypi.org> wrote: > 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> Patch applied for fixes with Stephen's ACK, I had to rebase it because of something, maybe whitespace mangling. Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index efcf2a2..547b925 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -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); }
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> --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 ++ 1 file changed, 2 insertions(+)