• Andy Shevchenko's avatar
    serial: 8250: Check UPF_IRQ_SHARED in advance · 7febbcbc
    Andy Shevchenko authored
    The commit 54e53b2e
      ("tty: serial: 8250: pass IRQ shared flag to UART ports")
    nicely explained the problem:
    
    ---8<---8<---
    
    On some systems IRQ lines between multiple UARTs might be shared. If so, the
    irqflags have to be configured accordingly. The reason is: The 8250 port startup
    code performs IRQ tests *before* the IRQ handler for that particular port is
    registered. This is performed in serial8250_do_startup(). This function checks
    whether IRQF_SHARED is configured and only then disables the IRQ line while
    testing.
    
    This test is performed upon each open() of the UART device. Imagine two UARTs
    share the same IRQ line: On is already opened and the IRQ is active. When the
    second UART is opened, the IRQ line has to be disabled while performing IRQ
    tests. Otherwise an IRQ might handler might be invoked, but the IRQ itself
    cannot be handled, because the corresponding handler isn't registered,
    yet. That's because the 8250 code uses a chain-handler and invokes the
    corresponding port's IRQ handling routines himself.
    
    Unfortunately this IRQF_SHARED flag isn't configured for UARTs probed via device
    tree even if the IRQs are shared. This way, the actual and shared IRQ line isn't
    disabled while performing tests and the kernel correctly detects a spurious
    IRQ. So, adding this flag to the DT probe solves the issue.
    
    Note: The UPF_SHARE_IRQ flag is configured unconditionally. Therefore, the
    IRQF_SHARED flag can be set unconditionally as well.
    
    Example stack trace by performing `echo 1 > /dev/ttyS2` on a non-patched system:
    
    |irq 85: nobody cared (try booting with the "irqpoll" option)
    | [...]
    |handlers:
    |[<ffff0000080fc628>] irq_default_primary_handler threaded [<ffff00000855fbb8>] serial8250_interrupt
    |Disabling IRQ #85
    
    ---8<---8<---
    
    But unfortunately didn't fix the root cause. Let's try again here by moving
    IRQ flag assignment from serial_link_irq_chain() to serial8250_do_startup().
    
    This should fix the similar issue reported for 8250_pnp case.
    
    Since this change we don't need to have custom solutions in 8250_aspeed_vuart
    and 8250_of drivers, thus, drop them.
    
    Fixes: 1c2f0493 ("serial: 8250: add IRQ trigger support")
    Reported-by: default avatarLi RongQing <lirongqing@baidu.com>
    Cc: Kurt Kanzenbach <kurt@linutronix.de>
    Cc: Vikram Pandita <vikram.pandita@ti.com>
    Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
    Cc: stable <stable@vger.kernel.org>
    Acked-by: Kurt Kanzenbach's avatarKurt Kanzenbach <kurt@linutronix.de>
    Link: https://lore.kernel.org/r/20200211135559.85960-1-andriy.shevchenko@linux.intel.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    7febbcbc
8250_port.c 80.5 KB