| From 0ebe5710335d98e589ac3611ae05e6e52c2643f7 Mon Sep 17 00:00:00 2001 |
| From: Geert Uytterhoeven <geert+renesas@glider.be> |
| Date: Mon, 2 Jun 2014 15:38:11 +0200 |
| Subject: spi: rspi: SPI DMA core needs both RX and TX DMA to function |
| |
| The SPI DMA core framework needs both RX and TX DMA to function. As a |
| preparation for converting the driver to use this framework, fall back to |
| PIO if no DMA channel or only one DMA channel is available. |
| |
| This affects only RSPI, which could do DMA transfers for TX-only before. |
| RSPI-RZ and QSPI (at least for Single SPI Transfers) will need both RX and |
| TX DMA anyway. |
| |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| Signed-off-by: Mark Brown <broonie@linaro.org> |
| (cherry picked from commit 5f338d0ce0b4c9e6c554b92cfb288789a41bfbc1) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/spi/spi-rspi.c | 36 ++++++++++++++---------------------- |
| 1 file changed, 14 insertions(+), 22 deletions(-) |
| |
| diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c |
| index 1ec51cb00203..7b993f75a3cf 100644 |
| --- a/drivers/spi/spi-rspi.c |
| +++ b/drivers/spi/spi-rspi.c |
| @@ -640,10 +640,6 @@ end_tx_mapped: |
| |
| static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t) |
| { |
| - /* If the module receives data by DMAC, it also needs TX DMAC */ |
| - if (t->rx_buf) |
| - return rspi->chan_tx && rspi->chan_rx; |
| - |
| if (rspi->chan_tx) |
| return 1; |
| |
| @@ -985,29 +981,25 @@ static int rspi_request_dma(struct device *dev, struct rspi_data *rspi, |
| { |
| const struct rspi_plat_data *rspi_pd = dev_get_platdata(dev); |
| |
| - if (!rspi_pd) |
| + if (!rspi_pd || !rspi_pd->dma_rx_id || !rspi_pd->dma_tx_id) |
| return 0; /* The driver assumes no error. */ |
| |
| - /* If the module receives data by DMAC, it also needs TX DMAC */ |
| - if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) { |
| - rspi->chan_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, |
| - rspi_pd->dma_rx_id, |
| - res->start + RSPI_SPDR); |
| - if (!rspi->chan_rx) |
| - return -ENODEV; |
| + rspi->chan_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, |
| + rspi_pd->dma_rx_id, |
| + res->start + RSPI_SPDR); |
| + if (!rspi->chan_rx) |
| + return -ENODEV; |
| |
| - dev_info(dev, "Use DMA when rx.\n"); |
| - } |
| - if (rspi_pd->dma_tx_id) { |
| - rspi->chan_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, |
| - rspi_pd->dma_tx_id, |
| - res->start + RSPI_SPDR); |
| - if (!rspi->chan_tx) |
| - return -ENODEV; |
| - |
| - dev_info(dev, "Use DMA when tx\n"); |
| + rspi->chan_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, |
| + rspi_pd->dma_tx_id, |
| + res->start + RSPI_SPDR); |
| + if (!rspi->chan_tx) { |
| + dma_release_channel(rspi->chan_rx); |
| + rspi->chan_rx = NULL; |
| + return -ENODEV; |
| } |
| |
| + dev_info(dev, "DMA available"); |
| return 0; |
| } |
| |
| -- |
| 2.1.2 |
| |