All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Revert "spi: omap2-mcspi: fix dma transfer for vmalloced buffer"
@ 2016-04-08 18:43 Akinobu Mita
       [not found] ` <1460140995-4062-1-git-send-email-akinobu.mita-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Akinobu Mita @ 2016-04-08 18:43 UTC (permalink / raw)
  To: linux-spi-u79uwXL29TY76Z2rM5mHXA; +Cc: Akinobu Mita, Mark Brown

This reverts commit 3525e0aac91c4de5d20b1f22a6c6e2b39db3cc96.

The DMA transfer for RX buffer was not handled correctly in this change.

The actual transfer length for DMA RX can be less than xfer->len in the
specific condition and the last words will be filled after the DMA
completion, but the commit doesn't consider it and the dmaengine is
started with rx_sg mapped by spi core.

The solution for this at least requires more lines than this commit
has inserted.  So revert it for now.

Signed-off-by: Akinobu Mita <akinobu.mita-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi-omap2-mcspi.c | 62 +++++++++++++++++++++++++++++++------------
 1 file changed, 45 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 43a02e3..0caa3c8 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -423,12 +423,16 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi,
 
 	if (mcspi_dma->dma_tx) {
 		struct dma_async_tx_descriptor *tx;
+		struct scatterlist sg;
 
 		dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);
 
-		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl,
-					     xfer->tx_sg.nents, DMA_MEM_TO_DEV,
-					     DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		sg_init_table(&sg, 1);
+		sg_dma_address(&sg) = xfer->tx_dma;
+		sg_dma_len(&sg) = xfer->len;
+
+		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1,
+		DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 		if (tx) {
 			tx->callback = omap2_mcspi_tx_callback;
 			tx->callback_param = spi;
@@ -474,15 +478,20 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 
 	if (mcspi_dma->dma_rx) {
 		struct dma_async_tx_descriptor *tx;
+		struct scatterlist sg;
 
 		dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
 
 		if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0)
 			dma_count -= es;
 
-		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, xfer->rx_sg.sgl,
-					     xfer->rx_sg.nents, DMA_DEV_TO_MEM,
-					     DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		sg_init_table(&sg, 1);
+		sg_dma_address(&sg) = xfer->rx_dma;
+		sg_dma_len(&sg) = dma_count;
+
+		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1,
+				DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT |
+				DMA_CTRL_ACK);
 		if (tx) {
 			tx->callback = omap2_mcspi_rx_callback;
 			tx->callback_param = spi;
@@ -496,6 +505,8 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	omap2_mcspi_set_dma_req(spi, 1, 1);
 
 	wait_for_completion(&mcspi_dma->dma_rx_completion);
+	dma_unmap_single(mcspi->dev, xfer->rx_dma, count,
+			 DMA_FROM_DEVICE);
 
 	if (mcspi->fifo_depth > 0)
 		return count;
@@ -608,6 +619,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
 
 	if (tx != NULL) {
 		wait_for_completion(&mcspi_dma->dma_tx_completion);
+		dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len,
+				 DMA_TO_DEVICE);
 
 		if (mcspi->fifo_depth > 0) {
 			irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS;
@@ -1074,16 +1087,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)
 		gpio_free(spi->cs_gpio);
 }
 
-static bool omap2_mcspi_can_dma(struct spi_master *master,
-				struct spi_device *spi,
-				struct spi_transfer *xfer)
-{
-	if (xfer->len < DMA_MIN_BYTES)
-		return false;
-
-	return true;
-}
-
 static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi,
 		struct spi_device *spi, struct spi_transfer *t)
 {
@@ -1265,6 +1268,32 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,
 		return -EINVAL;
 	}
 
+	if (len < DMA_MIN_BYTES)
+		goto skip_dma_map;
+
+	if (mcspi_dma->dma_tx && tx_buf != NULL) {
+		t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf,
+				len, DMA_TO_DEVICE);
+		if (dma_mapping_error(mcspi->dev, t->tx_dma)) {
+			dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
+					'T', len);
+			return -EINVAL;
+		}
+	}
+	if (mcspi_dma->dma_rx && rx_buf != NULL) {
+		t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len,
+				DMA_FROM_DEVICE);
+		if (dma_mapping_error(mcspi->dev, t->rx_dma)) {
+			dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
+					'R', len);
+			if (tx_buf != NULL)
+				dma_unmap_single(mcspi->dev, t->tx_dma,
+						len, DMA_TO_DEVICE);
+			return -EINVAL;
+		}
+	}
+
+skip_dma_map:
 	return omap2_mcspi_work_one(mcspi, spi, t);
 }
 
@@ -1348,7 +1377,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
 	master->transfer_one = omap2_mcspi_transfer_one;
 	master->set_cs = omap2_mcspi_set_cs;
 	master->cleanup = omap2_mcspi_cleanup;
-	master->can_dma = omap2_mcspi_can_dma;
 	master->dev.of_node = node;
 	master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ;
 	master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] Revert "spi: omap2-mcspi: fix dma transfer for vmalloced buffer"
       [not found] ` <1460140995-4062-1-git-send-email-akinobu.mita-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-04-12  1:22   ` Mark Brown
  2016-04-12  2:01   ` Applied "spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer" to the spi tree Mark Brown
  1 sibling, 0 replies; 8+ messages in thread
From: Mark Brown @ 2016-04-12  1:22 UTC (permalink / raw)
  To: Akinobu Mita; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 336 bytes --]

On Sat, Apr 09, 2016 at 03:43:15AM +0900, Akinobu Mita wrote:
> This reverts commit 3525e0aac91c4de5d20b1f22a6c6e2b39db3cc96.
> 
> The DMA transfer for RX buffer was not handled correctly in this change.

Please use subject lines reflecting the style for the subsystem.  This
makes it easier to spot relevant changes for review.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Applied "spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer" to the spi tree
       [not found] ` <1460140995-4062-1-git-send-email-akinobu.mita-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-04-12  1:22   ` Mark Brown
@ 2016-04-12  2:01   ` Mark Brown
  2016-05-11 15:39     ` Akinobu Mita
  1 sibling, 1 reply; 8+ messages in thread
From: Mark Brown @ 2016-04-12  2:01 UTC (permalink / raw)
  To: Akinobu Mita; +Cc: Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA, Mark Brown

The patch

   spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

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

>From 8070954d7c9fffa527e785292e901867338f79a9 Mon Sep 17 00:00:00 2001
From: Akinobu Mita <akinobu.mita-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Sat, 9 Apr 2016 03:43:15 +0900
Subject: [PATCH] spi: omap2-mcspi: Undo broken fix for dma transfer of
 vmalloced buffer

This reverts commit 3525e0aac91c4de5d20b1f22a6c6e2b39db3cc96.

The DMA transfer for RX buffer was not handled correctly in this change.

The actual transfer length for DMA RX can be less than xfer->len in the
specific condition and the last words will be filled after the DMA
completion, but the commit doesn't consider it and the dmaengine is
started with rx_sg mapped by spi core.

The solution for this at least requires more lines than this commit
has inserted.  So revert it for now.

Signed-off-by: Akinobu Mita <akinobu.mita-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi-omap2-mcspi.c | 62 +++++++++++++++++++++++++++++++------------
 1 file changed, 45 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 43a02e377b3b..0caa3c8bef46 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -423,12 +423,16 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi,
 
 	if (mcspi_dma->dma_tx) {
 		struct dma_async_tx_descriptor *tx;
+		struct scatterlist sg;
 
 		dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);
 
-		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl,
-					     xfer->tx_sg.nents, DMA_MEM_TO_DEV,
-					     DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		sg_init_table(&sg, 1);
+		sg_dma_address(&sg) = xfer->tx_dma;
+		sg_dma_len(&sg) = xfer->len;
+
+		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1,
+		DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 		if (tx) {
 			tx->callback = omap2_mcspi_tx_callback;
 			tx->callback_param = spi;
@@ -474,15 +478,20 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 
 	if (mcspi_dma->dma_rx) {
 		struct dma_async_tx_descriptor *tx;
+		struct scatterlist sg;
 
 		dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
 
 		if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0)
 			dma_count -= es;
 
-		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, xfer->rx_sg.sgl,
-					     xfer->rx_sg.nents, DMA_DEV_TO_MEM,
-					     DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		sg_init_table(&sg, 1);
+		sg_dma_address(&sg) = xfer->rx_dma;
+		sg_dma_len(&sg) = dma_count;
+
+		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1,
+				DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT |
+				DMA_CTRL_ACK);
 		if (tx) {
 			tx->callback = omap2_mcspi_rx_callback;
 			tx->callback_param = spi;
@@ -496,6 +505,8 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	omap2_mcspi_set_dma_req(spi, 1, 1);
 
 	wait_for_completion(&mcspi_dma->dma_rx_completion);
+	dma_unmap_single(mcspi->dev, xfer->rx_dma, count,
+			 DMA_FROM_DEVICE);
 
 	if (mcspi->fifo_depth > 0)
 		return count;
@@ -608,6 +619,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
 
 	if (tx != NULL) {
 		wait_for_completion(&mcspi_dma->dma_tx_completion);
+		dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len,
+				 DMA_TO_DEVICE);
 
 		if (mcspi->fifo_depth > 0) {
 			irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS;
@@ -1074,16 +1087,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)
 		gpio_free(spi->cs_gpio);
 }
 
-static bool omap2_mcspi_can_dma(struct spi_master *master,
-				struct spi_device *spi,
-				struct spi_transfer *xfer)
-{
-	if (xfer->len < DMA_MIN_BYTES)
-		return false;
-
-	return true;
-}
-
 static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi,
 		struct spi_device *spi, struct spi_transfer *t)
 {
@@ -1265,6 +1268,32 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,
 		return -EINVAL;
 	}
 
+	if (len < DMA_MIN_BYTES)
+		goto skip_dma_map;
+
+	if (mcspi_dma->dma_tx && tx_buf != NULL) {
+		t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf,
+				len, DMA_TO_DEVICE);
+		if (dma_mapping_error(mcspi->dev, t->tx_dma)) {
+			dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
+					'T', len);
+			return -EINVAL;
+		}
+	}
+	if (mcspi_dma->dma_rx && rx_buf != NULL) {
+		t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len,
+				DMA_FROM_DEVICE);
+		if (dma_mapping_error(mcspi->dev, t->rx_dma)) {
+			dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
+					'R', len);
+			if (tx_buf != NULL)
+				dma_unmap_single(mcspi->dev, t->tx_dma,
+						len, DMA_TO_DEVICE);
+			return -EINVAL;
+		}
+	}
+
+skip_dma_map:
 	return omap2_mcspi_work_one(mcspi, spi, t);
 }
 
@@ -1348,7 +1377,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
 	master->transfer_one = omap2_mcspi_transfer_one;
 	master->set_cs = omap2_mcspi_set_cs;
 	master->cleanup = omap2_mcspi_cleanup;
-	master->can_dma = omap2_mcspi_can_dma;
 	master->dev.of_node = node;
 	master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ;
 	master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15;
-- 
2.8.0.rc3

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: Applied "spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer" to the spi tree
  2016-04-12  2:01   ` Applied "spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer" to the spi tree Mark Brown
@ 2016-05-11 15:39     ` Akinobu Mita
       [not found]       ` <CAC5umyg2fJxYKOB4J96+3igkNx+eJs5MET8S8NnafZ3hcPPEag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Akinobu Mita @ 2016-05-11 15:39 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 523 bytes --]

2016-04-12 11:01 GMT+09:00 Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>:
> The patch
>
>    spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer
>
> has been applied to the spi tree at
>
>    git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git

I realized that this undo patch has not been merged to Linus' tree yet.
I have a fix for this issue (attached patch).  But the change is not
small and also v4.6 release is soon.  So I think this undo patch
should go into 4.6 release.

[-- Attachment #2: 0001-spi-omap2-mcspi-fix-dma-transfer.patch --]
[-- Type: text/x-patch, Size: 2840 bytes --]

From 5abc589ab08e239e884fb2e8937d74f81fb0b888 Mon Sep 17 00:00:00 2001
From: Akinobu Mita <akinobu.mita@gmail.com>
Date: Mon, 21 Mar 2016 01:16:06 +0900
Subject: [PATCH] spi: omap2-mcspi: fix dma transfer

This fixes the problem introduced by the commit 3525e0aac91c ("spi:
omap2-mcspi: fix dma transfer for vmalloced buffer")

The actual DMA transfer length by dmaengine can be smaller than SPI
transfer length in the specific condition.  In that case, the last
word needs to be filled after DMA transfer completion.

This fixes it by detecting that case and remap the scatterlist with
correct DMA transfer length.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
---
 drivers/spi/spi-omap2-mcspi.c | 47 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 43a02e3..a7fafd0 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -439,7 +439,41 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi,
 	}
 	dma_async_issue_pending(mcspi_dma->dma_tx);
 	omap2_mcspi_set_dma_req(spi, 0, 1);
+}
+
+static int
+omap2_mcspi_rx_dma_remap(struct spi_device *spi, struct spi_transfer *xfer,
+			 unsigned int dma_count)
+{
+	int i;
+	struct scatterlist *sg;
+	struct omap2_mcspi *mcspi;
+	unsigned int nents = 0;
+	unsigned int count = 0;
+	int ret;
+
+	mcspi = spi_master_get_devdata(spi->master);
+
+	dma_unmap_sg(mcspi->dev, xfer->rx_sg.sgl, xfer->rx_sg.nents,
+		     DMA_FROM_DEVICE);
+
+	for_each_sg(xfer->rx_sg.sgl, sg, xfer->rx_sg.nents, i) {
+		nents++;
+		if (count + sg->length < dma_count) {
+			count += sg->length;
+			continue;
+		}
+		sg->length = dma_count - count;
+		break;
+	}
 
+	ret = dma_map_sg(mcspi->dev, xfer->rx_sg.sgl, nents, DMA_FROM_DEVICE);
+	if (!ret)
+		return -ENOMEM;
+
+	xfer->rx_sg.nents = ret;
+
+	return 0;
 }
 
 static unsigned
@@ -480,6 +514,16 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 		if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0)
 			dma_count -= es;
 
+		if (xfer->len != dma_count) {
+			int ret;
+
+			ret = omap2_mcspi_rx_dma_remap(spi, xfer, dma_count);
+			if (ret) {
+				dev_err(&spi->dev, "failed to map rx buf\n");
+				return 0;
+			}
+		}
+
 		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, xfer->rx_sg.sgl,
 					     xfer->rx_sg.nents, DMA_DEV_TO_MEM,
 					     DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
@@ -496,6 +540,9 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 	omap2_mcspi_set_dma_req(spi, 1, 1);
 
 	wait_for_completion(&mcspi_dma->dma_rx_completion);
+	dma_unmap_sg(mcspi->dev, xfer->rx_sg.sgl, xfer->rx_sg.nents,
+		     DMA_FROM_DEVICE);
+	sg_free_table(&xfer->rx_sg);
 
 	if (mcspi->fifo_depth > 0)
 		return count;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: Applied "spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer" to the spi tree
       [not found]       ` <CAC5umyg2fJxYKOB4J96+3igkNx+eJs5MET8S8NnafZ3hcPPEag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-05-11 16:20         ` Mark Brown
       [not found]           ` <20160511162030.GN6261-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Mark Brown @ 2016-05-11 16:20 UTC (permalink / raw)
  To: Akinobu Mita; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 932 bytes --]

On Thu, May 12, 2016 at 12:39:35AM +0900, Akinobu Mita wrote:

> I realized that this undo patch has not been merged to Linus' tree yet.
> I have a fix for this issue (attached patch).  But the change is not
> small and also v4.6 release is soon.  So I think this undo patch
> should go into 4.6 release.

I actually just sent that a few minutes ago anyway.

> The actual DMA transfer length by dmaengine can be smaller than SPI
> transfer length in the specific condition.  In that case, the last
> word needs to be filled after DMA transfer completion.

> This fixes it by detecting that case and remap the scatterlist with
> correct DMA transfer length.

This feels like it should be in the framework, I imagine other devices
will have similar limiations.  Especially if the limitation comes from
the DMA engine I'd hope we can arrange to query it somehow...  can you
provide a bit more detail on what the restriction is please?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Applied "spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer" to the spi tree
       [not found]           ` <20160511162030.GN6261-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
@ 2016-05-12 13:49             ` Akinobu Mita
       [not found]               ` <CAC5umyjoKfMBbO1JPyTjqsz4zuiZMQDZcKHxonZuEwqGpJxb_g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Akinobu Mita @ 2016-05-12 13:49 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

2016-05-12 1:20 GMT+09:00 Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>:
> On Thu, May 12, 2016 at 12:39:35AM +0900, Akinobu Mita wrote:
>
>> I realized that this undo patch has not been merged to Linus' tree yet.
>> I have a fix for this issue (attached patch).  But the change is not
>> small and also v4.6 release is soon.  So I think this undo patch
>> should go into 4.6 release.
>
> I actually just sent that a few minutes ago anyway.
>
>> The actual DMA transfer length by dmaengine can be smaller than SPI
>> transfer length in the specific condition.  In that case, the last
>> word needs to be filled after DMA transfer completion.
>
>> This fixes it by detecting that case and remap the scatterlist with
>> correct DMA transfer length.
>
> This feels like it should be in the framework, I imagine other devices
> will have similar limiations.  Especially if the limitation comes from
> the DMA engine I'd hope we can arrange to query it somehow...  can you
> provide a bit more detail on what the restriction is please?

According to the source code (I couldn't find out the reason from TRM
yet), the last word (or two words if TURBO mode is used) of RX data
needs to be transferred by PIO transfer instead of DMA transfer.

But if FIFO buffer support[*] is used, the whole RX data can be
transferred by DMA transfer.  The use of FIFO buffer is determined by
omap2_mcspi_set_fifo() with the total transfer length, bits per words,
TX/RX only or both, and etc.

[*] commit d33f473dcd8e ("spi: omap2-mcspi: Add FIFO buffer support")

If we have an optional callback to get the actual DMA transfer length
instead of using spi_transfer->len for each spi_transfer in the
framework, we can use it to determine the correct map size used by
spi_map_buf() in spi.c.
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Applied "spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer" to the spi tree
       [not found]               ` <CAC5umyjoKfMBbO1JPyTjqsz4zuiZMQDZcKHxonZuEwqGpJxb_g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-05-12 15:44                 ` Mark Brown
       [not found]                   ` <20160512154436.GE6261-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Mark Brown @ 2016-05-12 15:44 UTC (permalink / raw)
  To: Akinobu Mita; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 473 bytes --]

On Thu, May 12, 2016 at 10:49:15PM +0900, Akinobu Mita wrote:

> If we have an optional callback to get the actual DMA transfer length
> instead of using spi_transfer->len for each spi_transfer in the
> framework, we can use it to determine the correct map size used by
> spi_map_buf() in spi.c.

That sounds plausible, we can also do some querying of the dmaengine at
the same place we call that when we get around to that.  Can you try to
come up with an implementation?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Applied "spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer" to the spi tree
       [not found]                   ` <20160512154436.GE6261-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
@ 2016-05-12 16:47                     ` Akinobu Mita
  0 siblings, 0 replies; 8+ messages in thread
From: Akinobu Mita @ 2016-05-12 16:47 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

2016-05-13 0:44 GMT+09:00 Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>:
> On Thu, May 12, 2016 at 10:49:15PM +0900, Akinobu Mita wrote:
>
>> If we have an optional callback to get the actual DMA transfer length
>> instead of using spi_transfer->len for each spi_transfer in the
>> framework, we can use it to determine the correct map size used by
>> spi_map_buf() in spi.c.
>
> That sounds plausible, we can also do some querying of the dmaengine at
> the same place we call that when we get around to that.  Can you try to
> come up with an implementation?

OK, I'll try and see how it looks like.
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-05-12 16:47 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-08 18:43 [PATCH] Revert "spi: omap2-mcspi: fix dma transfer for vmalloced buffer" Akinobu Mita
     [not found] ` <1460140995-4062-1-git-send-email-akinobu.mita-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-04-12  1:22   ` Mark Brown
2016-04-12  2:01   ` Applied "spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer" to the spi tree Mark Brown
2016-05-11 15:39     ` Akinobu Mita
     [not found]       ` <CAC5umyg2fJxYKOB4J96+3igkNx+eJs5MET8S8NnafZ3hcPPEag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-05-11 16:20         ` Mark Brown
     [not found]           ` <20160511162030.GN6261-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-05-12 13:49             ` Akinobu Mita
     [not found]               ` <CAC5umyjoKfMBbO1JPyTjqsz4zuiZMQDZcKHxonZuEwqGpJxb_g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-05-12 15:44                 ` Mark Brown
     [not found]                   ` <20160512154436.GE6261-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-05-12 16:47                     ` Akinobu Mita

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.