summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-bcm2835.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2018-11-28 15:55:24 +0000
committerMark Brown <broonie@kernel.org>2018-11-28 15:55:24 +0000
commitc06eea7d2a0ee79174c912810e0065d3f5c0d784 (patch)
tree4b182355c2ac80af9ab3c1b11d9fa2d358f7c443 /drivers/spi/spi-bcm2835.c
parent942779c6f1f899bc54332f7bb67666244f3f6d6c (diff)
parente82b0b3828451c1cd331d9f304c6078fcd43b62e (diff)
Merge branch 'spi-4.20' into spi-4.21 for bcm stuff.
Diffstat (limited to 'drivers/spi/spi-bcm2835.c')
-rw-r--r--drivers/spi/spi-bcm2835.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index b0b87ff936c7..43c6ca535800 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -155,8 +155,7 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id)
/* Write as many bytes as possible to FIFO */
bcm2835_wr_fifo(bs);
- /* based on flags decide if we can finish the transfer */
- if (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE) {
+ if (!bs->rx_len) {
/* Transfer complete - reset SPI HW */
bcm2835_spi_reset_hw(master);
/* wake up the framework */
@@ -233,10 +232,9 @@ static void bcm2835_spi_dma_done(void *data)
* is called the tx-dma must have finished - can't get to this
* situation otherwise...
*/
- dmaengine_terminate_all(master->dma_tx);
-
- /* mark as no longer pending */
- bs->dma_pending = 0;
+ if (cmpxchg(&bs->dma_pending, true, false)) {
+ dmaengine_terminate_all(master->dma_tx);
+ }
/* and mark as completed */;
complete(&master->xfer_completion);
@@ -342,6 +340,7 @@ static int bcm2835_spi_transfer_one_dma(struct spi_master *master,
if (ret) {
/* need to reset on errors */
dmaengine_terminate_all(master->dma_tx);
+ bs->dma_pending = false;
bcm2835_spi_reset_hw(master);
return ret;
}
@@ -617,10 +616,9 @@ static void bcm2835_spi_handle_err(struct spi_master *master,
struct bcm2835_spi *bs = spi_master_get_devdata(master);
/* if an error occurred and we have an active dma, then terminate */
- if (bs->dma_pending) {
+ if (cmpxchg(&bs->dma_pending, true, false)) {
dmaengine_terminate_all(master->dma_tx);
dmaengine_terminate_all(master->dma_rx);
- bs->dma_pending = 0;
}
/* and reset */
bcm2835_spi_reset_hw(master);