From eafdb06d3c03960c266dddb798438962b6c88a48 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 29 Sep 2026 13:41:32 +0100 Subject: [PATCH 1/2] misc: rp1-pio: Use the correct dev in dma_free Although it hasn't been an issue due to the specifics of the Pi 5 platform, DMA buffers should be allocated and freed with the same "dev" parameter. Guarantee that by deriving the dev pointer from the given dma_info pointer. Signed-off-by: Phil Elwell --- drivers/misc/rp1-pio.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/misc/rp1-pio.c b/drivers/misc/rp1-pio.c index 0a57960d8a60a..8a70469e1daa6 100644 --- a/drivers/misc/rp1-pio.c +++ b/drivers/misc/rp1-pio.c @@ -1002,18 +1002,21 @@ static void rp1_pio_sm_dma_flush_rx(struct dma_info *dma) dma_free_coherent(dma_dev, len, buf, dma_addr); } -static void rp1_pio_sm_dma_free(struct device *dev, struct dma_info *dma) +static void rp1_pio_sm_dma_free(struct dma_info *dma) { + /* The buffers were allocated for the DMA controller, so free them there */ + struct device *dma_dev = dma->chan->device->dev; + dmaengine_terminate_all(dma->chan); if (dma->cyclic) { dma->buf_count = 0; - dma_free_coherent(dev, ROUND_UP(dma->buf_size, PAGE_SIZE), + dma_free_coherent(dma_dev, ROUND_UP(dma->buf_size, PAGE_SIZE), dma->bufs[0].buf, dma->bufs[0].dma_addr); } else { while (dma->buf_count > 0) { dma->buf_count--; - dma_free_coherent(dev, ROUND_UP(dma->buf_size, PAGE_SIZE), + dma_free_coherent(dma_dev, ROUND_UP(dma->buf_size, PAGE_SIZE), dma->bufs[dma->buf_count].buf, dma->bufs[dma->buf_count].dma_addr); } @@ -1068,7 +1071,7 @@ static int rp1_pio_sm_config_xfer_internal(struct rp1_pio_client *client, uint s /* dma_release_channel() sleeps, so free the old channel outside the lock. */ if (reconfigure) - rp1_pio_sm_dma_free(dev, dma); + rp1_pio_sm_dma_free(dma); sema_init(&dma->buf_sem, 0); @@ -1199,7 +1202,7 @@ static int rp1_pio_sm_config_xfer_internal(struct rp1_pio_client *client, uint s return 0; err_dma_free: - rp1_pio_sm_dma_free(dev, dma); + rp1_pio_sm_dma_free(dma); err_unclaim: spin_lock(&pio->lock); @@ -1712,7 +1715,7 @@ void rp1_pio_close(struct rp1_pio_client *client) /* The SMs have been disabled, so this is safe */ if ((i & 1) == RP1_PIO_DIR_FROM_SM) rp1_pio_sm_dma_flush_rx(dma); - rp1_pio_sm_dma_free(&pio->pdev->dev, dma); + rp1_pio_sm_dma_free(dma); } } From 684c1d5737fcb675acf8dba4a8c87c19669f0559 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 29 Sep 2026 15:22:13 +0100 Subject: [PATCH 2/2] misc: rp1-pio: Minor cyclic DMA error path fixes 1. Set dma->cyclic earlier so it is available to rp1_pio_sm_dma_free in the error path. 2. Set an error code in the case that the cyclic preparation fails. Signed-off-by: Phil Elwell --- drivers/misc/rp1-pio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/misc/rp1-pio.c b/drivers/misc/rp1-pio.c index 8a70469e1daa6..1ade2a3abed0f 100644 --- a/drivers/misc/rp1-pio.c +++ b/drivers/misc/rp1-pio.c @@ -1101,7 +1101,7 @@ static int rp1_pio_sm_config_xfer_internal(struct rp1_pio_client *client, uint s if (cyclic) { dma->buf_size = buf_size * buf_count; - dma->buf_count = buf_count; + dma->buf_count = 0; /* Round up the allocations */ buf_size = ROUND_UP(dma->buf_size, PAGE_SIZE); @@ -1116,6 +1116,8 @@ static int rp1_pio_sm_config_xfer_internal(struct rp1_pio_client *client, uint s } sg_init_table(&dbi->sgl, 1); sg_dma_address(&dbi->sgl) = dbi->dma_addr; + dma->buf_count = buf_count; + dma->cyclic = cyclic; } else { dma->buf_size = buf_size; /* Round up the allocations */ @@ -1185,6 +1187,7 @@ static int rp1_pio_sm_config_xfer_internal(struct rp1_pio_client *client, uint s DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { dev_err(dev, "DMA preparation failed\n"); + ret = -EIO; goto err_dma_free; } @@ -1196,7 +1199,6 @@ static int rp1_pio_sm_config_xfer_internal(struct rp1_pio_client *client, uint s if (ret < 0) goto err_dma_free; - dma->cyclic = cyclic; dma_async_issue_pending(dma->chan); } return 0;