summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMacpaul Lin <[email protected]>2026-04-06 15:13:33 -0500
committerDavid Lechner <[email protected]>2026-04-28 13:11:19 -0500
commit28bd63967784d1dbeff75289560e71fd1deac902 (patch)
tree0118b7deeee9fbfc743402ac763495439ab97275 /drivers
parent1cfcd7100d54b706b7d4ee17dd016b83e5eb88ff (diff)
spi: mtk_snor: fix zeroed data in DMA read bounce path
Implement proper bounce buffer handling for the read path to fix zeroed data when using DMA. In the bounce path, map the bounce buffer with dma_map_single(), perform DMA using bounce_dma, then copy data from the bounce buffer to the user buffer, and finally unmap with dma_unmap_single(). Signed-off-by: Macpaul Lin <[email protected]> Reviewed-by: Julien Stephan <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: David Lechner <[email protected]>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/mtk_snor.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/spi/mtk_snor.c b/drivers/spi/mtk_snor.c
index 649bca5716c..21ac115e3c3 100644
--- a/drivers/spi/mtk_snor.c
+++ b/drivers/spi/mtk_snor.c
@@ -274,6 +274,7 @@ static int mtk_snor_read_bounce(struct mtk_snor_priv *priv,
{
unsigned int rdlen;
int ret;
+ dma_addr_t bounce_dma;
if (op->data.nbytes & MTK_NOR_DMA_ALIGN_MASK)
rdlen = (op->data.nbytes + MTK_NOR_DMA_ALIGN) &
@@ -281,11 +282,21 @@ static int mtk_snor_read_bounce(struct mtk_snor_priv *priv,
else
rdlen = op->data.nbytes;
- ret = mtk_snor_dma_exec(priv, op->addr.val, rdlen,
- (dma_addr_t)priv->buffer);
+ /* Map bounce buffer for DMA */
+ bounce_dma = dma_map_single(priv->buffer, rdlen, DMA_FROM_DEVICE);
+ if (dma_mapping_error(priv->dev, bounce_dma)) {
+ dev_err(priv->dev, "bounce buffer dma map failed\n");
+ return -EINVAL;
+ }
- if (!ret)
+ ret = mtk_snor_dma_exec(priv, op->addr.val, rdlen, bounce_dma);
+ /* Ensure DMA writes are visible to CPU and copy the requested bytes */
+ if (!ret) {
+ /* Synchronize cached data to CPU visible memory if needed */
memcpy(op->data.buf.in, priv->buffer, op->data.nbytes);
+ }
+ /* Unmap bounce buffer regardless of success/failure */
+ dma_unmap_single(bounce_dma, rdlen, DMA_FROM_DEVICE);
return ret;
}