summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFan Wu <fanwu01@zju.edu.cn>2026-07-31 08:59:15 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-08-03 16:31:22 +0200
commit440915499231e9db1c361aa45bb702e8fd3b4a32 (patch)
treeb8b67de4cd868844833719e36482426edf256cf9
parent36672c8d7d14e9c43287528455d2c97b526ea6ad (diff)
serial: amba-pl011: synchronize DMA teardown
dmaengine_terminate_all() does not wait for a running callback, so the TX callback can still touch the TX buffer after it is freed. The RX poll timer reads the RX buffers without the port lock. Switch to dmaengine_terminate_sync() and delete the RX timer before freeing the buffers. Fixes: ead76f329f77 ("ARM: 6763/1: pl011: add optional RX DMA to PL011 v2") Cc: stable <stable@kernel.org> Assisted-by: Codex:gpt-5.6 Signed-off-by: Fan Wu <fanwu01@zju.edu.cn> Link: https://patch.msgid.link/20260731085915.326775-4-fanwu01@zju.edu.cn Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/amba-pl011.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 5232042fdd92..9abaeecd05fc 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1247,7 +1247,7 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)
if (uap->using_tx_dma) {
/* In theory, this should already be done by pl011_dma_flush_buffer */
- dmaengine_terminate_all(uap->dmatx.chan);
+ dmaengine_terminate_sync(uap->dmatx.chan);
if (uap->dmatx.queued) {
dma_unmap_single(uap->dmatx.chan->device->dev,
uap->dmatx.dma, uap->dmatx.len,
@@ -1260,12 +1260,12 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)
}
if (uap->using_rx_dma) {
- dmaengine_terminate_all(uap->dmarx.chan);
+ if (uap->dmarx.poll_rate)
+ timer_delete_sync(&uap->dmarx.timer);
+ dmaengine_terminate_sync(uap->dmarx.chan);
/* Clean up the RX DMA */
pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_a, DMA_FROM_DEVICE);
pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_b, DMA_FROM_DEVICE);
- if (uap->dmarx.poll_rate)
- timer_delete_sync(&uap->dmarx.timer);
uap->using_rx_dma = false;
}
}