Merge remote-tracking branch 'spi/fix/sh-msiof' into spi-linus
This commit is contained in:
commit
e0a7ab4b50
@ -636,6 +636,26 @@ 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;
|
||||||
|
|
||||||
|
/* First prepare and submit the DMA request(s), as this may fail */
|
||||||
|
if (rx) {
|
||||||
|
ier_bits |= IER_RDREQE | IER_RDMAE;
|
||||||
|
desc_rx = dmaengine_prep_slave_single(p->master->dma_rx,
|
||||||
|
p->rx_dma_addr, len, DMA_FROM_DEVICE,
|
||||||
|
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||||
|
if (!desc_rx) {
|
||||||
|
ret = -EAGAIN;
|
||||||
|
goto no_dma_rx;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc_rx->callback = sh_msiof_dma_complete;
|
||||||
|
desc_rx->callback_param = p;
|
||||||
|
cookie = dmaengine_submit(desc_rx);
|
||||||
|
if (dma_submit_error(cookie)) {
|
||||||
|
ret = cookie;
|
||||||
|
goto no_dma_rx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tx) {
|
if (tx) {
|
||||||
ier_bits |= IER_TDREQE | IER_TDMAE;
|
ier_bits |= IER_TDREQE | IER_TDMAE;
|
||||||
dma_sync_single_for_device(p->master->dma_tx->device->dev,
|
dma_sync_single_for_device(p->master->dma_tx->device->dev,
|
||||||
@ -643,17 +663,23 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
|
|||||||
desc_tx = dmaengine_prep_slave_single(p->master->dma_tx,
|
desc_tx = dmaengine_prep_slave_single(p->master->dma_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 -EAGAIN;
|
ret = -EAGAIN;
|
||||||
}
|
goto no_dma_tx;
|
||||||
|
}
|
||||||
|
|
||||||
if (rx) {
|
if (rx) {
|
||||||
ier_bits |= IER_RDREQE | IER_RDMAE;
|
/* No callback */
|
||||||
desc_rx = dmaengine_prep_slave_single(p->master->dma_rx,
|
desc_tx->callback = NULL;
|
||||||
p->rx_dma_addr, len, DMA_FROM_DEVICE,
|
} else {
|
||||||
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
desc_tx->callback = sh_msiof_dma_complete;
|
||||||
if (!desc_rx)
|
desc_tx->callback_param = p;
|
||||||
return -EAGAIN;
|
}
|
||||||
|
cookie = dmaengine_submit(desc_tx);
|
||||||
|
if (dma_submit_error(cookie)) {
|
||||||
|
ret = cookie;
|
||||||
|
goto no_dma_tx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1 stage FIFO watermarks for DMA */
|
/* 1 stage FIFO watermarks for DMA */
|
||||||
@ -666,37 +692,16 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
|
|||||||
|
|
||||||
reinit_completion(&p->done);
|
reinit_completion(&p->done);
|
||||||
|
|
||||||
if (rx) {
|
/* Now start DMA */
|
||||||
desc_rx->callback = sh_msiof_dma_complete;
|
if (tx)
|
||||||
desc_rx->callback_param = p;
|
|
||||||
cookie = dmaengine_submit(desc_rx);
|
|
||||||
if (dma_submit_error(cookie)) {
|
|
||||||
ret = cookie;
|
|
||||||
goto stop_ier;
|
|
||||||
}
|
|
||||||
dma_async_issue_pending(p->master->dma_rx);
|
dma_async_issue_pending(p->master->dma_rx);
|
||||||
}
|
if (rx)
|
||||||
|
|
||||||
if (tx) {
|
|
||||||
if (rx) {
|
|
||||||
/* No callback */
|
|
||||||
desc_tx->callback = NULL;
|
|
||||||
} else {
|
|
||||||
desc_tx->callback = sh_msiof_dma_complete;
|
|
||||||
desc_tx->callback_param = p;
|
|
||||||
}
|
|
||||||
cookie = dmaengine_submit(desc_tx);
|
|
||||||
if (dma_submit_error(cookie)) {
|
|
||||||
ret = cookie;
|
|
||||||
goto stop_rx;
|
|
||||||
}
|
|
||||||
dma_async_issue_pending(p->master->dma_tx);
|
dma_async_issue_pending(p->master->dma_tx);
|
||||||
}
|
|
||||||
|
|
||||||
ret = sh_msiof_spi_start(p, rx);
|
ret = sh_msiof_spi_start(p, rx);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&p->pdev->dev, "failed to start hardware\n");
|
dev_err(&p->pdev->dev, "failed to start hardware\n");
|
||||||
goto stop_tx;
|
goto stop_dma;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for tx fifo to be emptied / rx fifo to be filled */
|
/* wait for tx fifo to be emptied / rx fifo to be filled */
|
||||||
@ -726,14 +731,14 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
|
|||||||
stop_reset:
|
stop_reset:
|
||||||
sh_msiof_reset_str(p);
|
sh_msiof_reset_str(p);
|
||||||
sh_msiof_spi_stop(p, rx);
|
sh_msiof_spi_stop(p, rx);
|
||||||
stop_tx:
|
stop_dma:
|
||||||
if (tx)
|
if (tx)
|
||||||
dmaengine_terminate_all(p->master->dma_tx);
|
dmaengine_terminate_all(p->master->dma_tx);
|
||||||
stop_rx:
|
no_dma_tx:
|
||||||
if (rx)
|
if (rx)
|
||||||
dmaengine_terminate_all(p->master->dma_rx);
|
dmaengine_terminate_all(p->master->dma_rx);
|
||||||
stop_ier:
|
|
||||||
sh_msiof_write(p, IER, 0);
|
sh_msiof_write(p, IER, 0);
|
||||||
|
no_dma_rx:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user