Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: s3c64xx: move dma_release_channel to unprepare

This fixes the sequence of dma_release_channel.
Since commit f52b03c70744 ("spi: s3c64xx: requests spi-dma channel only
during data transfer"),
dma_release_channel has been located in the s3c64xx_spi_transfer_one
but this makes invalid return of can_dma callback.
__spi_unmap_msg will check whether the request is requested by dma or
not via can_dma callback. When it is calling to check it, the channels
will be already released at the end of s3c64xx_spi_transfer_one so the
callback function will return always "false". So, they can't be unmapped
from __spi_unmap_msg call. To fix this, we need to add
unprepare_transfer_hardware callback and move the dma_release_channel
from s3c64xx_spi_transfer_one to there.

Fixes: f52b03c70744 ("spi: s3c64xx: requests spi-dma channel only during data transfer")
Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Link: https://lore.kernel.org/r/20220627013845.138350-1-chanho61.park@samsung.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Chanho Park and committed by
Mark Brown
82295bc0 917e43de

+19 -8
+19 -8
drivers/spi/spi-s3c64xx.c
··· 373 373 return 0; 374 374 } 375 375 376 + static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) 377 + { 378 + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); 379 + 380 + if (is_polling(sdd)) 381 + return 0; 382 + 383 + /* Releases DMA channels if they are allocated */ 384 + if (sdd->rx_dma.ch && sdd->tx_dma.ch) { 385 + dma_release_channel(sdd->rx_dma.ch); 386 + dma_release_channel(sdd->tx_dma.ch); 387 + sdd->rx_dma.ch = 0; 388 + sdd->tx_dma.ch = 0; 389 + } 390 + 391 + return 0; 392 + } 393 + 376 394 static bool s3c64xx_spi_can_dma(struct spi_master *master, 377 395 struct spi_device *spi, 378 396 struct spi_transfer *xfer) ··· 822 804 xfer->len = origin_len; 823 805 } 824 806 825 - /* Releases DMA channels after data transfer is completed */ 826 - if (sdd->rx_dma.ch && sdd->tx_dma.ch) { 827 - dma_release_channel(sdd->rx_dma.ch); 828 - dma_release_channel(sdd->tx_dma.ch); 829 - sdd->rx_dma.ch = NULL; 830 - sdd->tx_dma.ch = NULL; 831 - } 832 - 833 807 return status; 834 808 } 835 809 ··· 1138 1128 master->setup = s3c64xx_spi_setup; 1139 1129 master->cleanup = s3c64xx_spi_cleanup; 1140 1130 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; 1131 + master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; 1141 1132 master->prepare_message = s3c64xx_spi_prepare_message; 1142 1133 master->transfer_one = s3c64xx_spi_transfer_one; 1143 1134 master->num_chipselect = sci->num_cs;