diff mbox

spi: omap2-mcspi: In case of dma errors fall back to pio

Message ID 1343197229-15188-1-git-send-email-shubhrajyoti@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Shubhrajyoti Datta July 25, 2012, 6:20 a.m. UTC
In case there are dma errors currently the driver exits.
Make the spi driver fall back to pio mode in case of dma errors.

If the DMA engine is not selected the driver
exits.This patch makes the spi fall back to pio in that case.

Also adds a field dma_unusable to struct omap2_mcspi.
 
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
 drivers/spi/spi-omap2-mcspi.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)

Comments

Tony Lindgren Aug. 7, 2012, 7:47 a.m. UTC | #1
* Shubhrajyoti D <shubhrajyoti@ti.com> [120724 23:26]:
> In case there are dma errors currently the driver exits.
> Make the spi driver fall back to pio mode in case of dma errors.
> 
> If the DMA engine is not selected the driver
> exits.This patch makes the spi fall back to pio in that case.
> 
> Also adds a field dma_unusable to struct omap2_mcspi.
>  
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
>  drivers/spi/spi-omap2-mcspi.c |   21 +++++++++++++--------
>  1 files changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
> index bc47781..f243a39 100644
> --- a/drivers/spi/spi-omap2-mcspi.c
> +++ b/drivers/spi/spi-omap2-mcspi.c
> @@ -129,6 +129,7 @@ struct omap2_mcspi {
>  	struct omap2_mcspi_dma	*dma_channels;
>  	struct device		*dev;
>  	struct omap2_mcspi_regs ctx;
> +	int dma_unusable;
>  };

Don't you need to check separately for rx and tx dma? There's a slight
chance that you get a channel for one but not for the other..

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Shubhrajyoti Datta Aug. 7, 2012, 11:21 a.m. UTC | #2
On Tuesday 07 August 2012 01:17 PM, Tony Lindgren wrote:
>>  };
> Don't you need to check separately for rx and tx dma? There's a slight
> chance that you get a channel for one but not for the other..
In that case I treat it as non usable and fall back to pio.

Are you suggesting that let one channel be dma and only the failed one pio?
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tony Lindgren Aug. 7, 2012, 12:02 p.m. UTC | #3
* Shubhrajyoti <shubhrajyoti@ti.com> [120807 04:21]:
> On Tuesday 07 August 2012 01:17 PM, Tony Lindgren wrote:
> >>  };
> > Don't you need to check separately for rx and tx dma? There's a slight
> > chance that you get a channel for one but not for the other..
> In that case I treat it as non usable and fall back to pio.

OK that should work too.
 
> Are you suggesting that let one channel be dma and only the failed one pio?

I guess both are doable. For reduced CPU load using DMA where possible
of course is the best way to go.

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Felipe Balbi Aug. 7, 2012, 12:21 p.m. UTC | #4
Hi,

On Tue, Aug 07, 2012 at 05:02:27AM -0700, Tony Lindgren wrote:
> * Shubhrajyoti <shubhrajyoti@ti.com> [120807 04:21]:
> > On Tuesday 07 August 2012 01:17 PM, Tony Lindgren wrote:
> > >>  };
> > > Don't you need to check separately for rx and tx dma? There's a slight
> > > chance that you get a channel for one but not for the other..
> > In that case I treat it as non usable and fall back to pio.
> 
> OK that should work too.
>  
> > Are you suggesting that let one channel be dma and only the failed one pio?
> 
> I guess both are doable. For reduced CPU load using DMA where possible
> of course is the best way to go.

indeed. if you can get DMA for TX but not for RX, then at least TX can
go via DMA ;-)
avinash philip Aug. 8, 2012, 2:39 p.m. UTC | #5
On Wed, Jul 25, 2012 at 11:50:29, Datta, Shubhrajyoti wrote:
> In case there are dma errors currently the driver exits.
> Make the spi driver fall back to pio mode in case of dma errors.
> 
> If the DMA engine is not selected the driver
> exits.This patch makes the spi fall back to pio in that case.
> 
> Also adds a field dma_unusable to struct omap2_mcspi.
>  
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>

I have tested this patch for SPI PIO mode on AM335x EVM.

Acked-by: Philip, Avinash <avinashphilip@ti.com>

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

Patch

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index bc47781..f243a39 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -129,6 +129,7 @@  struct omap2_mcspi {
 	struct omap2_mcspi_dma	*dma_channels;
 	struct device		*dev;
 	struct omap2_mcspi_regs ctx;
+	int dma_unusable;
 };
 
 struct omap2_mcspi_cs {
@@ -845,7 +846,7 @@  static int omap2_mcspi_setup(struct spi_device *spi)
 	if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) {
 		ret = omap2_mcspi_request_dma(spi);
 		if (ret < 0)
-			return ret;
+			mcspi->dma_unusable = 1;
 	}
 
 	ret = omap2_mcspi_enable_clocks(mcspi);
@@ -956,7 +957,8 @@  static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
 				__raw_writel(0, cs->base
 						+ OMAP2_MCSPI_TX0);
 
-			if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES)
+			if (!mcspi->dma_unusable && (m->is_dma_mapped ||
+						t->len >= DMA_MIN_BYTES))
 				count = omap2_mcspi_txrx_dma(spi, t);
 			else
 				count = omap2_mcspi_txrx_pio(spi, t);
@@ -1030,7 +1032,8 @@  static int omap2_mcspi_transfer_one_message(struct spi_master *master,
 			return -EINVAL;
 		}
 
-		if (m->is_dma_mapped || len < DMA_MIN_BYTES)
+		if (mcspi->dma_unusable || m->is_dma_mapped ||
+					len < DMA_MIN_BYTES)
 			continue;
 
 		if (tx_buf != NULL) {
@@ -1054,6 +1057,7 @@  static int omap2_mcspi_transfer_one_message(struct spi_master *master,
 				return -EINVAL;
 			}
 		}
+
 	}
 
 	omap2_mcspi_work(mcspi, m);
@@ -1216,9 +1220,12 @@  static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
 		mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start;
 	}
 
-	if (status < 0)
-		goto dma_chnl_free;
-
+	if (status < 0) {
+		dev_err(&pdev->dev, "cannot get DMA channel switching to pio\n");
+		mcspi->dma_unusable = 1;
+		status = 0;
+		kfree(mcspi->dma_channels);
+	}
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
 	pm_runtime_enable(&pdev->dev);
@@ -1229,14 +1236,12 @@  static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
 	status = spi_register_master(master);
 	if (status < 0)
 		goto err_spi_register;
-
 	return status;
 
 err_spi_register:
 	spi_master_put(master);
 disable_pm:
 	pm_runtime_disable(&pdev->dev);
-dma_chnl_free:
 	kfree(mcspi->dma_channels);
 free_master:
 	kfree(master);