提交 279d2378 编写于 作者: G Geert Uytterhoeven 提交者: Mark Brown

spi: sh-msiof: Handle dmaengine_prep_slave_single() failures gracefully

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_single() may start failing
arbitrarily.

Handle dmaengine_prep_slave_single() failures gracefully by falling back to
PIO. This requires moving DMA-specific configuration of the MSIOF device
after the call(s) to dmaengine_prep_slave_single().
Signed-off-by: NGeert Uytterhoeven <geert+renesas@glider.be>
Acked-by: NLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: NMark Brown <broonie@linaro.org>
上级 51fd5090
...@@ -636,12 +636,6 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, ...@@ -636,12 +636,6 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
dma_cookie_t cookie; dma_cookie_t cookie;
int ret; int ret;
/* 1 stage FIFO watermarks for DMA */
sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1);
/* setup msiof transfer mode registers (32-bit words) */
sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4);
if (tx) { if (tx) {
ier_bits |= IER_TDREQE | IER_TDMAE; ier_bits |= IER_TDREQE | IER_TDMAE;
dma_sync_single_for_device(&p->pdev->dev, p->tx_dma_addr, len, dma_sync_single_for_device(&p->pdev->dev, p->tx_dma_addr, len,
...@@ -650,7 +644,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, ...@@ -650,7 +644,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
p->tx_dma_addr, len, DMA_TO_DEVICE, p->tx_dma_addr, len, DMA_TO_DEVICE,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK); DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx) if (!desc_tx)
return -EIO; return -EAGAIN;
} }
if (rx) { if (rx) {
...@@ -659,8 +653,15 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, ...@@ -659,8 +653,15 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
p->rx_dma_addr, len, DMA_FROM_DEVICE, p->rx_dma_addr, len, DMA_FROM_DEVICE,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK); DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_rx) if (!desc_rx)
return -EIO; return -EAGAIN;
} }
/* 1 stage FIFO watermarks for DMA */
sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1);
/* setup msiof transfer mode registers (32-bit words) */
sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4);
sh_msiof_write(p, IER, ier_bits); sh_msiof_write(p, IER, ier_bits);
reinit_completion(&p->done); reinit_completion(&p->done);
...@@ -822,6 +823,12 @@ static int sh_msiof_transfer_one(struct spi_master *master, ...@@ -822,6 +823,12 @@ static int sh_msiof_transfer_one(struct spi_master *master,
copy32(p->tx_dma_page, tx_buf, l / 4); copy32(p->tx_dma_page, tx_buf, l / 4);
ret = sh_msiof_dma_once(p, tx_buf, rx_buf, l); ret = sh_msiof_dma_once(p, tx_buf, rx_buf, l);
if (ret == -EAGAIN) {
pr_warn_once("%s %s: DMA not available, falling back to PIO\n",
dev_driver_string(&p->pdev->dev),
dev_name(&p->pdev->dev));
break;
}
if (ret) if (ret)
return ret; return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册