Skip to content

Commit

Permalink
spi: rspi: Handle dmaengine_prep_slave_sg() failures gracefully
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Geert Uytterhoeven authored and Mark Brown committed Jul 16, 2014
1 parent 533465a commit 85912a8
Showing 1 changed file with 22 additions and 8 deletions.
30 changes: 22 additions & 8 deletions drivers/spi/spi-rspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
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;
}
Expand All @@ -486,7 +486,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
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;
}
Expand Down Expand Up @@ -540,6 +540,12 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
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)
Expand Down Expand Up @@ -593,8 +599,10 @@ static int rspi_common_transfer(struct rspi_data *rspi,

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);
Expand Down Expand Up @@ -648,8 +656,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
{
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)
Expand All @@ -663,8 +674,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)

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);
}
Expand Down

0 comments on commit 85912a8

Please sign in to comment.