Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit da56009

Browse files
andy-shevbroonie
authored andcommitted
spi: Check if transfer is mapped before calling DMA sync APIs
The resent update to remove the orig_nents checks revealed that not all DMA sync backends can cope with the unallocated SG list, while supplying orig_nents == 0 (the commit 861370f ("iommu/dma: force bouncing if the size is not cacheline-aligned"), for example, makes that happen for the IOMMU case). It means we have to check if the buffers are DMA mapped before trying to sync them. Re-introduce that check in a form of calling ->can_dma() in the same way as it's done in the DMA mapping loop for the SPI transfers. Reported-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> Reported-by: Neil Armstrong <neil.armstrong@linaro.org> Closes: https://lore.kernel.org/r/8ae675b5-fcf9-4c9b-b06a-4462f70e1322@linaro.org Closes: https://lore.kernel.org/all/d3679496-2e4e-4a7c-97ed-f193bd53af1d@notapiano Fixes: 8cc3bad ("spi: Remove unneded check for orig_nents") Suggested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://msgid.link/r/20240522171018.3362521-3-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 9f788ba commit da56009

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

drivers/spi/spi.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,7 +1311,7 @@ static int __spi_unmap_msg(struct spi_controller *ctlr, struct spi_message *msg)
13111311
return 0;
13121312
}
13131313

1314-
static void spi_dma_sync_for_device(struct spi_controller *ctlr,
1314+
static void spi_dma_sync_for_device(struct spi_controller *ctlr, struct spi_message *msg,
13151315
struct spi_transfer *xfer)
13161316
{
13171317
struct device *rx_dev = ctlr->cur_rx_dma_dev;
@@ -1320,11 +1320,14 @@ static void spi_dma_sync_for_device(struct spi_controller *ctlr,
13201320
if (!ctlr->cur_msg_mapped)
13211321
return;
13221322

1323+
if (!ctlr->can_dma(ctlr, msg->spi, xfer))
1324+
return;
1325+
13231326
dma_sync_sgtable_for_device(tx_dev, &xfer->tx_sg, DMA_TO_DEVICE);
13241327
dma_sync_sgtable_for_device(rx_dev, &xfer->rx_sg, DMA_FROM_DEVICE);
13251328
}
13261329

1327-
static void spi_dma_sync_for_cpu(struct spi_controller *ctlr,
1330+
static void spi_dma_sync_for_cpu(struct spi_controller *ctlr, struct spi_message *msg,
13281331
struct spi_transfer *xfer)
13291332
{
13301333
struct device *rx_dev = ctlr->cur_rx_dma_dev;
@@ -1333,6 +1336,9 @@ static void spi_dma_sync_for_cpu(struct spi_controller *ctlr,
13331336
if (!ctlr->cur_msg_mapped)
13341337
return;
13351338

1339+
if (!ctlr->can_dma(ctlr, msg->spi, xfer))
1340+
return;
1341+
13361342
dma_sync_sgtable_for_cpu(rx_dev, &xfer->rx_sg, DMA_FROM_DEVICE);
13371343
dma_sync_sgtable_for_cpu(tx_dev, &xfer->tx_sg, DMA_TO_DEVICE);
13381344
}
@@ -1350,11 +1356,13 @@ static inline int __spi_unmap_msg(struct spi_controller *ctlr,
13501356
}
13511357

13521358
static void spi_dma_sync_for_device(struct spi_controller *ctrl,
1359+
struct spi_message *msg,
13531360
struct spi_transfer *xfer)
13541361
{
13551362
}
13561363

13571364
static void spi_dma_sync_for_cpu(struct spi_controller *ctrl,
1365+
struct spi_message *msg,
13581366
struct spi_transfer *xfer)
13591367
{
13601368
}
@@ -1626,10 +1634,10 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
16261634
reinit_completion(&ctlr->xfer_completion);
16271635

16281636
fallback_pio:
1629-
spi_dma_sync_for_device(ctlr, xfer);
1637+
spi_dma_sync_for_device(ctlr, msg, xfer);
16301638
ret = ctlr->transfer_one(ctlr, msg->spi, xfer);
16311639
if (ret < 0) {
1632-
spi_dma_sync_for_cpu(ctlr, xfer);
1640+
spi_dma_sync_for_cpu(ctlr, msg, xfer);
16331641

16341642
if (ctlr->cur_msg_mapped &&
16351643
(xfer->error & SPI_TRANS_FAIL_NO_START)) {
@@ -1654,7 +1662,7 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
16541662
msg->status = ret;
16551663
}
16561664

1657-
spi_dma_sync_for_cpu(ctlr, xfer);
1665+
spi_dma_sync_for_cpu(ctlr, msg, xfer);
16581666
} else {
16591667
if (xfer->len)
16601668
dev_err(&msg->spi->dev,

0 commit comments

Comments
 (0)