提交 6b6192c0 编写于 作者: S Sascha Hauer 提交者: Mark Brown

spi: imx: drop bogus tests for rx/tx bufs in DMA transfer

The driver tries to be clever by only setting up DMA channels when
the corresponding sg tables are non NULL. The sg tables are embedded
structs in struct spi_transfer, so they are guaranteed to be non NULL
which makes the if(tx)/if(rx) tests completely bogus. The driver even
sets the SPI_MASTER_MUST_RX / SPI_MASTER_MUST_TX flags which makes sure
the sg tables are not only present but also non empty.
Drop the tests and make the DMA path easier to follow.
Signed-off-by: NSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: NMark Brown <broonie@kernel.org>
上级 b03c3884
......@@ -974,51 +974,40 @@ static int spi_imx_calculate_timeout(struct spi_imx_data *spi_imx, int size)
static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
struct spi_transfer *transfer)
{
struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL;
int ret;
struct dma_async_tx_descriptor *desc_tx, *desc_rx;
unsigned long transfer_timeout;
unsigned long timeout;
struct spi_master *master = spi_imx->bitbang.master;
struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg;
if (tx) {
desc_tx = dmaengine_prep_slave_sg(master->dma_tx,
tx->sgl, tx->nents, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx)
return -EINVAL;
desc_tx->callback = spi_imx_dma_tx_callback;
desc_tx->callback_param = (void *)spi_imx;
dmaengine_submit(desc_tx);
}
/*
* The TX DMA setup starts the transfer, so make sure RX is configured
* before TX.
*/
desc_rx = dmaengine_prep_slave_sg(master->dma_rx,
rx->sgl, rx->nents, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_rx)
return -EINVAL;
if (rx) {
desc_rx = dmaengine_prep_slave_sg(master->dma_rx,
rx->sgl, rx->nents, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_rx) {
dmaengine_terminate_all(master->dma_tx);
return -EINVAL;
}
desc_rx->callback = spi_imx_dma_rx_callback;
desc_rx->callback_param = (void *)spi_imx;
dmaengine_submit(desc_rx);
reinit_completion(&spi_imx->dma_rx_completion);
dma_async_issue_pending(master->dma_rx);
desc_rx->callback = spi_imx_dma_rx_callback;
desc_rx->callback_param = (void *)spi_imx;
dmaengine_submit(desc_rx);
desc_tx = dmaengine_prep_slave_sg(master->dma_tx,
tx->sgl, tx->nents, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx) {
dmaengine_terminate_all(master->dma_tx);
return -EINVAL;
}
reinit_completion(&spi_imx->dma_rx_completion);
desc_tx->callback = spi_imx_dma_tx_callback;
desc_tx->callback_param = (void *)spi_imx;
dmaengine_submit(desc_tx);
reinit_completion(&spi_imx->dma_tx_completion);
/*
* Set these order to avoid potential RX overflow. The overflow may
* happen if we enable SPI HW before starting RX DMA due to rescheduling
* for another task and/or interrupt.
* So RX DMA enabled first to make sure data would be read out from FIFO
* ASAP. TX DMA enabled next to start filling TX FIFO with new data.
* And finaly SPI HW enabled to start actual data transfer.
*/
dma_async_issue_pending(master->dma_rx);
dma_async_issue_pending(master->dma_tx);
transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len);
......@@ -1030,22 +1019,19 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
dev_err(spi_imx->dev, "I/O Error in DMA TX\n");
dmaengine_terminate_all(master->dma_tx);
dmaengine_terminate_all(master->dma_rx);
} else {
timeout = wait_for_completion_timeout(
&spi_imx->dma_rx_completion, transfer_timeout);
if (!timeout) {
dev_err(spi_imx->dev, "I/O Error in DMA RX\n");
spi_imx->devtype_data->reset(spi_imx);
dmaengine_terminate_all(master->dma_rx);
}
return -ETIMEDOUT;
}
if (!timeout)
ret = -ETIMEDOUT;
else
ret = transfer->len;
timeout = wait_for_completion_timeout(&spi_imx->dma_rx_completion,
transfer_timeout);
if (!timeout) {
dev_err(&master->dev, "I/O Error in DMA RX\n");
spi_imx->devtype_data->reset(spi_imx);
dmaengine_terminate_all(master->dma_rx);
return -ETIMEDOUT;
}
return ret;
return transfer->len;
}
static int spi_imx_pio_transfer(struct spi_device *spi,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册