gpio-omap: gpio irq storm causes Linux unresponsive

XMLWordPrintable

    • Type: Bug
    • Resolution: Fixed
    • Priority: Medium
    • Linux Core SDK
    • LCPD-37502
    • 09.03
    • 09.03
    • Hide
      am335x-evm
      am335x-sk
      beaglebone-black
      Show
      am335x-evm am335x-sk beaglebone-black

      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

       

            Assignee:
            TI User
            Reporter:
            TI User
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:

                Connection: Intermediate to External PROD System
                EXTSYNC-5006 - gpio-omap: gpio irq storm causes Li...
                SYNCHRONIZED
                • Last Sync Date: