From 361e4d4dfdbaa4168695387ed4e20d4fb8ea67de Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 21 Jun 2022 15:22:17 +0000 Subject: [PATCH] NVIDIA: SAUCE: tty: serial: amba-pl011: fix deadlock with lpbk BugLink: https://bugs.launchpad.net/bugs/2080908 Hang is seen when UART if UART transfers are closed abruptly. The issue is seen only when the UART is running in DMA mode with internal loopback and HW Flow control enabled. When force termination happens on UART loopback transfers, the RX stops before TX. This makes TX to wait for CTS to toggle, which never happens. This renders UART as busy and makes the driver to wait endlessly before terminating the DMA transfers. To fix this, disable HW flow control during the UART shutdown if loopback is used. http://nvbugs/3684799 http://nvbugs/4754882 Signed-off-by: Kartik Tested-by: Petlozu Pravareshwar Reviewed-by: Petlozu Pravareshwar Signed-off-by: Laxman Dewangan Acked-by: Noah Wager Acked-by: Jacob Martin Signed-off-by: Noah Wager --- drivers/tty/serial/amba-pl011.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index cf5d50ab45f0..5bda3dd197eb 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1204,9 +1204,17 @@ skip_rx: static void pl011_dma_shutdown(struct uart_amba_port *uap) { + unsigned int cr; if (!(uap->using_tx_dma || uap->using_rx_dma)) return; + /* Fix potential deadlock when UART loopback is enabled. */ + cr = pl011_read(uap, REG_CR); + if (cr & UART011_CR_LBE) { + cr &= ~(UART011_CR_RTSEN | UART011_CR_CTSEN); + pl011_write(cr, uap, REG_CR); + } + /* Disable RX and TX DMA */ while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy) cpu_relax();