3.16.62-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven geert+renesas@glider.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@glider.be Acked-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mark Brown broonie@linaro.org Signed-off-by: Ben Hutchings ben@decadent.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); }