[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1544392233.806695552@decadent.org.uk>
Date: Sun, 09 Dec 2018 21:50:33 +0000
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org,
"Laurent Pinchart" <laurent.pinchart@...asonboard.com>,
"Geert Uytterhoeven" <geert+renesas@...der.be>,
"Mark Brown" <broonie@...aro.org>
Subject: [PATCH 3.16 203/328] spi: rspi: Handle dmaengine_prep_slave_sg()
failures gracefully
3.16.62-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <geert+renesas@...der.be>
commit 85912a88c1ebcad04a5cfec971771195ce8d6691 upstream.
As typically a shmobile SoC has less DMA channels than devices that can use
DMA, we may want to prioritize access to the DMA channels in the future.
This means that dmaengine_prep_slave_sg() may start failing arbitrarily.
Handle dmaengine_prep_slave_sg() failures gracefully by falling back to
PIO.
Signed-off-by: Geert Uytterhoeven <geert+renesas@...der.be>
Acked-by: Laurent Pinchart <laurent.pinchart@...asonboard.com>
Signed-off-by: Mark Brown <broonie@...aro.org>
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
drivers/spi/spi-rspi.c | 30 ++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -477,7 +477,7 @@ static int rspi_dma_transfer(struct rspi
tx->sgl, tx->nents, DMA_TO_DEVICE,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx)
- return -EIO;
+ goto no_dma;
irq_mask |= SPCR_SPTIE;
}
@@ -486,7 +486,7 @@ static int rspi_dma_transfer(struct rspi
rx->sgl, rx->nents, DMA_FROM_DEVICE,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_rx)
- return -EIO;
+ goto no_dma;
irq_mask |= SPCR_SPRIE;
}
@@ -540,6 +540,12 @@ static int rspi_dma_transfer(struct rspi
enable_irq(rspi->rx_irq);
return ret;
+
+no_dma:
+ pr_warn_once("%s %s: DMA not available, falling back to PIO\n",
+ dev_driver_string(&rspi->master->dev),
+ dev_name(&rspi->master->dev));
+ return -EAGAIN;
}
static void rspi_receive_init(const struct rspi_data *rspi)
@@ -593,8 +599,10 @@ static int rspi_common_transfer(struct r
if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
/* rx_buf can be NULL on RSPI on SH in TX-only Mode */
- return rspi_dma_transfer(rspi, &xfer->tx_sg,
- xfer->rx_buf ? &xfer->rx_sg : NULL);
+ ret = rspi_dma_transfer(rspi, &xfer->tx_sg,
+ xfer->rx_buf ? &xfer->rx_sg : NULL);
+ if (ret != -EAGAIN)
+ return ret;
}
ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len);
@@ -648,8 +656,11 @@ static int qspi_transfer_out(struct rspi
{
int ret;
- if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer))
- return rspi_dma_transfer(rspi, &xfer->tx_sg, NULL);
+ if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
+ ret = rspi_dma_transfer(rspi, &xfer->tx_sg, NULL);
+ if (ret != -EAGAIN)
+ return ret;
+ }
ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len);
if (ret < 0)
@@ -663,8 +674,11 @@ static int qspi_transfer_out(struct rspi
static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
{
- if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer))
- return rspi_dma_transfer(rspi, NULL, &xfer->rx_sg);
+ if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
+ int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg);
+ if (ret != -EAGAIN)
+ return ret;
+ }
return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len);
}
Powered by blists - more mailing lists