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 <macpaul.lin@mediatek.com>
Reviewed-by: Julien Stephan <jstephan@baylibre.com>
Link: https://patch.msgid.link/20260406-mtk-spi-nor-improvements-v1-7-66f675cbbd3e@baylibre.com
Signed-off-by: David Lechner <dlechner@baylibre.com>
This commit is contained in:
Macpaul Lin
2026-04-06 15:13:33 -05:00
committed by David Lechner
parent 1cfcd7100d
commit 28bd639677

View File

@@ -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;
}