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 <kkartik@nvidia.com>
Tested-by: Petlozu Pravareshwar <petlozup@nvidia.com>
Reviewed-by: Petlozu Pravareshwar <petlozup@nvidia.com>
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Acked-by: Noah Wager <noah.wager@canonical.com>
Acked-by: Jacob Martin <jacob.martin@canonical.com>
Signed-off-by: Noah Wager <noah.wager@canonical.com>
This commit is contained in:
Kartik
2022-06-21 15:22:17 +00:00
committed by Noah Wager
parent 0096d71b82
commit 361e4d4dfd
+8
View File
@@ -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();