summaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2019-09-11 12:15:30 +0200
committerMark Brown <broonie@kernel.org>2019-09-11 15:52:53 +0100
commit4f2228cce2816e46dcac0be50a259a0311a90252 (patch)
treea0cedf42f78838413fc044cf153a5ad7a91c6cdb /drivers/dma
parent1513ceee70f2bd523e025efe0c715328e1a43ffd (diff)
downloadlinux-4f2228cce2816e46dcac0be50a259a0311a90252.tar.bz2
dmaengine: bcm2835: Allow cyclic transactions without interrupt
The BCM2835 DMA driver currently requests an interrupt from the controller regardless whether or not the client has passed in the DMA_PREP_INTERRUPT flag. This causes unnecessary overhead for cyclic transactions which do not need an interrupt after each period. We're about to add such a use case, namely cyclic clearing of the SPI controller's RX FIFO, so amend the DMA driver to request an interrupt only if DMA_PREP_INTERRUPT was passed in. Ignore the period_len for such transactions and set it to the buffer length to make the driver's calculations work. Tested-by: Nuno Sá <nuno.sa@analog.com> Tested-by: Noralf Trønnes <noralf@tronnes.org> Signed-off-by: Lukas Wunner <lukas@wunner.de> Acked-by: Vinod Koul <vkoul@kernel.org> Acked-by: Stefan Wahren <wahrenst@gmx.net> Acked-by: Martin Sperl <kernel@martin.sperl.org> Cc: Florian Kauer <florian.kauer@koalo.de> Link: https://lore.kernel.org/r/73cf37be56eb4cbe6f696057c719f3a38cbaf26e.1568187525.git.lukas@wunner.de Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/bcm2835-dma.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 8101ff2f05c1..b40fb555b98b 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -691,7 +691,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
struct bcm2835_desc *d;
dma_addr_t src, dst;
u32 info = BCM2835_DMA_WAIT_RESP;
- u32 extra = BCM2835_DMA_INT_EN;
+ u32 extra = 0;
size_t max_len = bcm2835_dma_max_frame_length(c);
size_t frames;
@@ -707,6 +707,11 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
return NULL;
}
+ if (flags & DMA_PREP_INTERRUPT)
+ extra |= BCM2835_DMA_INT_EN;
+ else
+ period_len = buf_len;
+
/*
* warn if buf_len is not a multiple of period_len - this may leed
* to unexpected latencies for interrupts and thus audiable clicks
@@ -778,7 +783,10 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan)
/* stop DMA activity */
if (c->desc) {
- vchan_terminate_vdesc(&c->desc->vd);
+ if (c->desc->vd.tx.flags & DMA_PREP_INTERRUPT)
+ vchan_terminate_vdesc(&c->desc->vd);
+ else
+ vchan_vdesc_fini(&c->desc->vd);
c->desc = NULL;
bcm2835_dma_abort(c);
}