diff mbox series

spi: s3c64xx: move dma_release_channel to unprepare

Message ID 20220627013845.138350-1-chanho61.park@samsung.com (mailing list archive)
State Accepted
Commit 82295bc0d192d7e35e0568b18ca66da2c3058fd5
Headers show
Series spi: s3c64xx: move dma_release_channel to unprepare | expand

Commit Message

Chanho Park June 27, 2022, 1:38 a.m. UTC
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>
---
 drivers/spi/spi-s3c64xx.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

Comments

Mark Brown June 28, 2022, 10:31 a.m. UTC | #1
On Mon, 27 Jun 2022 10:38:45 +0900, Chanho Park wrote:
> 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.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: s3c64xx: move dma_release_channel to unprepare
      commit: 82295bc0d192d7e35e0568b18ca66da2c3058fd5

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark
diff mbox series

Patch

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 819b660dae82..7f0faf0d75d9 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -373,6 +373,24 @@  static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
 	return 0;
 }
 
+static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)
+{
+	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
+
+	if (is_polling(sdd))
+		return 0;
+
+	/* Releases DMA channels if they are allocated */
+	if (sdd->rx_dma.ch && sdd->tx_dma.ch) {
+		dma_release_channel(sdd->rx_dma.ch);
+		dma_release_channel(sdd->tx_dma.ch);
+		sdd->rx_dma.ch = 0;
+		sdd->tx_dma.ch = 0;
+	}
+
+	return 0;
+}
+
 static bool s3c64xx_spi_can_dma(struct spi_master *master,
 				struct spi_device *spi,
 				struct spi_transfer *xfer)
@@ -804,14 +822,6 @@  static int s3c64xx_spi_transfer_one(struct spi_master *master,
 		xfer->len = origin_len;
 	}
 
-	/* Releases DMA channels after data transfer is completed */
-	if (sdd->rx_dma.ch && sdd->tx_dma.ch) {
-		dma_release_channel(sdd->rx_dma.ch);
-		dma_release_channel(sdd->tx_dma.ch);
-		sdd->rx_dma.ch = NULL;
-		sdd->tx_dma.ch = NULL;
-	}
-
 	return status;
 }
 
@@ -1128,6 +1138,7 @@  static int s3c64xx_spi_probe(struct platform_device *pdev)
 	master->setup = s3c64xx_spi_setup;
 	master->cleanup = s3c64xx_spi_cleanup;
 	master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
+	master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
 	master->prepare_message = s3c64xx_spi_prepare_message;
 	master->transfer_one = s3c64xx_spi_transfer_one;
 	master->num_chipselect = sci->num_cs;