diff mbox

[REGRESSION] d7b4394e breaks bi-directional DMA transfers on omap2-mcspi

Message ID CAM=Q2ctN8nGvmbzO8K-hMeUKsp9kVbPxvO=OidkJZcLBfqOTLQ@mail.gmail.com (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Shubhrajyoti Datta Oct. 31, 2012, 1:57 p.m. UTC
On Wed, Oct 31, 2012 at 5:46 PM, Sørensen, Stefan
<Stefan.Sorensen@polycom.com> wrote:
> Bi-directional SPI transfers using DMA no longer works on omap2-mcspi after
> this commit:
My bad.

>
> commit d7b4394e780b02511c8a7a499380cdd56316c770
> Author: Shubhrajyoti D <shubhrajyoti@ti.com>
> Date:   Tue Sep 11 12:13:20 2012 +0530
>
>     spi: omap2-mcspi: Cleanup the omap2_mcspi_txrx_dma function
>
>     Currently in omap2_mcspi_txrx_dma the tx and the rx support is
>     interleaved. Make the rx related code in omap2_mcspi_rx_dma
>     and the tx related code omap2_mcspi_tx_dma and call the functions.
>
>     While at it remove the braces in the if statements which has only
>     one line.
>     Also fix ["foo * bar" to "foo *bar"] warn for the rx and tx variables.
>
>     Only a cleanup no functional change.
>
>     Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
>     Tested-by: Felipe Balbi <balbi@ti.com>
>     Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
>
>
> Basically the patch changes the pattern
>         start_tx();
>         start_rx();
>         wait_for_completion(tx);
>         wait_for_completion(tx);
> into
>         start_tx();
>         wait_for_completion(tx);
>         start_rx();
>         wait_for_completion(tx);
> which will stall the transfer since the rx channel is not serviced.

So moving the tx completion.

Apologies for breaking in the original commit.


Will test and get back with a proper patch.
---
 drivers/spi/spi-omap2-mcspi.c |   34 ++++++++++++++++------------------
 1 files changed, 16 insertions(+), 18 deletions(-)

 	mcspi_dma = &mcspi->dma_channels[spi->chip_select];
@@ -528,6 +511,21 @@ omap2_mcspi_txrx_dma(struct spi_device *spi,
struct spi_transfer *xfer)
 	if (rx != NULL)
 		return omap2_mcspi_rx_dma(spi, xfer, cfg, es);

+	chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
+	wait_for_completion(&mcspi_dma->dma_tx_completion);
+	dma_unmap_single(mcspi->dev, xfer->tx_dma, count,
+			 DMA_TO_DEVICE);
+
+	/* for TX_ONLY mode, be sure all words have shifted out */
+	if (rx == NULL) {
+		if (mcspi_wait_for_reg_bit(chstat_reg,
+					OMAP2_MCSPI_CHSTAT_TXS) < 0)
+			dev_err(&spi->dev, "TXS timed out\n");
+		else if (mcspi_wait_for_reg_bit(chstat_reg,
+					OMAP2_MCSPI_CHSTAT_EOT) < 0)
+			dev_err(&spi->dev, "EOT timed out\n");
+	}
+
 	return count;
 }
diff mbox

Patch

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 3542fdc..e8e5bbc 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -323,18 +323,13 @@  static void omap2_mcspi_tx_dma(struct spi_device *spi,
 	struct omap2_mcspi	*mcspi;
 	struct omap2_mcspi_dma  *mcspi_dma;
 	unsigned int		count;
-	u8			* rx;
 	const u8		* tx;
-	void __iomem		*chstat_reg;
-	struct omap2_mcspi_cs	*cs = spi->controller_state;

 	mcspi = spi_master_get_devdata(spi->master);
 	mcspi_dma = &mcspi->dma_channels[spi->chip_select];
 	count = xfer->len;

-	rx = xfer->rx_buf;
 	tx = xfer->tx_buf;
-	chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;

 	if (mcspi_dma->dma_tx) {
 		struct dma_async_tx_descriptor *tx;
@@ -359,19 +354,6 @@  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);

-	wait_for_completion(&mcspi_dma->dma_tx_completion);
-	dma_unmap_single(mcspi->dev, xfer->tx_dma, count,
-			 DMA_TO_DEVICE);
-
-	/* for TX_ONLY mode, be sure all words have shifted out */
-	if (rx == NULL) {
-		if (mcspi_wait_for_reg_bit(chstat_reg,
-					OMAP2_MCSPI_CHSTAT_TXS) < 0)
-			dev_err(&spi->dev, "TXS timed out\n");
-		else if (mcspi_wait_for_reg_bit(chstat_reg,
-					OMAP2_MCSPI_CHSTAT_EOT) < 0)
-			dev_err(&spi->dev, "EOT timed out\n");
-	}
 }

 static unsigned
@@ -492,6 +474,7 @@  omap2_mcspi_txrx_dma(struct spi_device *spi,
struct spi_transfer *xfer)
 	struct dma_slave_config	cfg;
 	enum dma_slave_buswidth width;
 	unsigned es;
+	void __iomem		*chstat_reg;

 	mcspi = spi_master_get_devdata(spi->master);