• Anssi Hannula's avatar
    serial: uartps: Fix stuck ISR if RX disabled with non-empty FIFO · 7abab160
    Anssi Hannula authored
    If RX is disabled while there are still unprocessed bytes in RX FIFO,
    cdns_uart_handle_rx() called from interrupt handler will get stuck in
    the receive loop as read bytes will not get removed from the RX FIFO
    and CDNS_UART_SR_RXEMPTY bit will never get set.
    
    Avoid the stuck handler by checking first if RX is disabled. port->lock
    protects against race with RX-disabling functions.
    
    This HW behavior was mentioned by Nathan Rossi in 43e98facc4a3 ("tty:
    xuartps: Fix RX hang, and TX corruption in termios call") which fixed a
    similar issue in cdns_uart_set_termios().
    The behavior can also be easily verified by e.g. setting
    CDNS_UART_CR_RX_DIS at the beginning of cdns_uart_handle_rx() - the
    following loop will then get stuck.
    
    Resetting the FIFO using RXRST would not set RXEMPTY either so simply
    issuing a reset after RX-disable would not work.
    
    I observe this frequently on a ZynqMP board during heavy RX load at 1M
    baudrate when the reader process exits and thus RX gets disabled.
    
    Fixes: 61ec9016 ("tty/serial: add support for Xilinx PS UART")
    Signed-off-by: default avatarAnssi Hannula <anssi.hannula@bitwise.fi>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    7abab160
xilinx_uartps.c 49.9 KB