-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Medium
-
Linux Core SDK
-
LCPD-37502
-
09.03
-
09.03
-
Applying a high frequency signal on a GPIO pin would trigger a IRQ storm, then kernel would detect it and disable this irq, but Linux is still unresponsive as long as the signal is still applied.
This issue is applicable to all devices which use gpio-omap.c driver, but here is the procedure to reproduce the issue on Beaglebone Black.
- Boot BBB with SDK9.1 default SD card WIC image;
- Run command 'gpiomon 0 12 &' (ensure gpiochip0 points to GPIO1 bank);
- Apply 200KHz signal (could be a PWM signal from another EVM) to pin GPIO1_12 (P8.12);
- kernel would detect the storm and disable the IRQ;
- Linux console is still unresponsive.
The root cause is the corresponding GPIO pin interrupt is not disabled. The following patch solves the issue:
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 80ddc43fd875..54dbf44c04b2 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -708,6 +708,27 @@ static void omap_gpio_unmask_irq(struct irq_data *d) raw_spin_unlock_irqrestore(&bank->lock, flags); } +static void omap_gpio_disable_irq(struct irq_data *d) +{ + struct gpio_bank *bank = omap_irq_data_get_bank(d); + unsigned offset = d->hwirq; + unsigned long flags; + + raw_spin_lock_irqsave(&bank->lock, flags); + omap_set_gpio_irqenable(bank, offset, 0); + raw_spin_unlock_irqrestore(&bank->lock, flags); +} +static void omap_gpio_enable_irq(struct irq_data *d) +{ + struct gpio_bank *bank = omap_irq_data_get_bank(d); + unsigned offset = d->hwirq; + unsigned long flags; + + raw_spin_lock_irqsave(&bank->lock, flags); + omap_set_gpio_irqenable(bank, offset, 1); + raw_spin_unlock_irqrestore(&bank->lock, flags); +} + /*---------------------------------------------------------------------*/ static int omap_mpuio_suspend_noirq(struct device *dev) @@ -1398,6 +1419,8 @@ static int omap_gpio_probe(struct platform_device *pdev) irqc->irq_ack = dummy_irq_chip.irq_ack, irqc->irq_mask = omap_gpio_mask_irq, irqc->irq_unmask = omap_gpio_unmask_irq, + irqc->irq_disable = omap_gpio_disable_irq, + irqc->irq_enable = omap_gpio_enable_irq, irqc->irq_set_type = omap_gpio_irq_type, irqc->irq_set_wake = omap_gpio_wake_enable, irqc->irq_bus_lock = omap_gpio_irq_bus_lock,
Link to the customer report:
https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1323640/beagl-bone-black-regression-linux-6-1-46-remains-unresponsive-after-disabling-interrupt-associated-to-gpio-pin-with-high-frequency-signal