diff options
author | Mark Brown <broonie@kernel.org> | 2018-11-28 18:55:24 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-11-28 18:55:24 +0300 |
commit | c06eea7d2a0ee79174c912810e0065d3f5c0d784 (patch) | |
tree | 4b182355c2ac80af9ab3c1b11d9fa2d358f7c443 /drivers/spi/spi-bcm2835.c | |
parent | 942779c6f1f899bc54332f7bb67666244f3f6d6c (diff) | |
parent | e82b0b3828451c1cd331d9f304c6078fcd43b62e (diff) | |
download | linux-c06eea7d2a0ee79174c912810e0065d3f5c0d784.tar.xz |
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.c | 14 |
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); |