mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 02:09:42 +00:00
dmaengine-fix-5.1-rc7
dmaengine fixes for v5.1-rc7 - fix for wrong register use in mediatek driver - fix in sh driver for glitch is tx_status and treating 0 a valid reside for cyclic - fix in bcm driver for using right memory allocation flag -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJcxUSOAAoJEHwUBw8lI4NHRxsQAIXJ5bRc9yWRBAnKtAboJjsD LosSArrM8B8aJSvVB/N+5F7gvpHc4lwq+XIhS+v7SR9PYuyNv1kETccswtIb/Ua1 okEiBYQbKab4yk5wnoejBZFWLu4OXmx0q1+tY9K7zvoXzc+mAuKwpfzGAGeYptCP 9jyMP7l/YfpnoPdySwTmyCKdpBw37fOOC3XIK938RQ5ktCVYJsg9K6YYb6gcnOXW DY0Nq64KmGnQYTU1R7YcQ5gXclCX4OE2bnbIOh6nKHEoDmHnw9DFnCP4m54R6yKk WljgyIViQe4tjljQB/jh6Crs3NE4fAJAdoMQq7ZOkwCOmjdPz3ZvzJjxGM+kZNb8 iWrkbSG9D46Ico7FNpatSQlav6Nmwl+NLrGxEyFu4BWUbIk8fTRu3toGn+LRvjU7 s7aO6nizlFX5Dc0YNswwq7k5NrDguOHrhk5wp1JP8XZ1Q0rhZAKNiCbYMJx+JVd+ zvbcoppLyVCx6KPhiNSr+wSBZDIvblZofz2CiMtYzzhTJBimdAIeY5ruJA2/OeSJ MHDIAGbbukWcdAg5AhT5RpVP1u8gzfJ6bk/K7cGLc4DP41Qh+kH9D335S0352/F3 6mT/KJI4LkjrL643sPmb1bQTNCrhwqKhf7ycuney3Tax+vWhGDOog3QidaYnvsvN dLQ6MCpciQR41cgsoYGt =qu54 -----END PGP SIGNATURE----- Merge tag 'dmaengine-fix-5.1-rc7' of git://git.infradead.org/users/vkoul/slave-dma Pull dmaengine fixes from Vinod Koul: - fix for wrong register use in mediatek driver - fix in sh driver for glitch is tx_status and treating 0 a valid residue for cyclic - fix in bcm driver for using right memory allocation flag * tag 'dmaengine-fix-5.1-rc7' of git://git.infradead.org/users/vkoul/slave-dma: dmaengine: mediatek-cqdma: fix wrong register usage in mtk_cqdma_start dmaengine: sh: rcar-dmac: Fix glitch in dmaengine_tx_status dmaengine: sh: rcar-dmac: With cyclic DMA residue 0 is valid dmaengine: bcm2835: Avoid GFP_KERNEL in device_prep_slave_sg
This commit is contained in:
commit
72a6e35db3
3 changed files with 28 additions and 6 deletions
|
@ -671,7 +671,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
|
|||
d = bcm2835_dma_create_cb_chain(chan, direction, false,
|
||||
info, extra,
|
||||
frames, src, dst, 0, 0,
|
||||
GFP_KERNEL);
|
||||
GFP_NOWAIT);
|
||||
if (!d)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ static void mtk_cqdma_start(struct mtk_cqdma_pchan *pc,
|
|||
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||
mtk_dma_set(pc, MTK_CQDMA_DST2, cvd->dest >> MTK_CQDMA_ADDR2_SHFIT);
|
||||
#else
|
||||
mtk_dma_set(pc, MTK_CQDMA_SRC2, 0);
|
||||
mtk_dma_set(pc, MTK_CQDMA_DST2, 0);
|
||||
#endif
|
||||
|
||||
/* setup the length */
|
||||
|
|
|
@ -1282,6 +1282,9 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
|
|||
enum dma_status status;
|
||||
unsigned int residue = 0;
|
||||
unsigned int dptr = 0;
|
||||
unsigned int chcrb;
|
||||
unsigned int tcrb;
|
||||
unsigned int i;
|
||||
|
||||
if (!desc)
|
||||
return 0;
|
||||
|
@ -1329,6 +1332,24 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to read two registers.
|
||||
* Make sure the control register does not skip to next chunk
|
||||
* while reading the counter.
|
||||
* Trying it 3 times should be enough: Initial read, retry, retry
|
||||
* for the paranoid.
|
||||
*/
|
||||
for (i = 0; i < 3; i++) {
|
||||
chcrb = rcar_dmac_chan_read(chan, RCAR_DMACHCRB) &
|
||||
RCAR_DMACHCRB_DPTR_MASK;
|
||||
tcrb = rcar_dmac_chan_read(chan, RCAR_DMATCRB);
|
||||
/* Still the same? */
|
||||
if (chcrb == (rcar_dmac_chan_read(chan, RCAR_DMACHCRB) &
|
||||
RCAR_DMACHCRB_DPTR_MASK))
|
||||
break;
|
||||
}
|
||||
WARN_ONCE(i >= 3, "residue might be not continuous!");
|
||||
|
||||
/*
|
||||
* In descriptor mode the descriptor running pointer is not maintained
|
||||
* by the interrupt handler, find the running descriptor from the
|
||||
|
@ -1336,8 +1357,7 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
|
|||
* mode just use the running descriptor pointer.
|
||||
*/
|
||||
if (desc->hwdescs.use) {
|
||||
dptr = (rcar_dmac_chan_read(chan, RCAR_DMACHCRB) &
|
||||
RCAR_DMACHCRB_DPTR_MASK) >> RCAR_DMACHCRB_DPTR_SHIFT;
|
||||
dptr = chcrb >> RCAR_DMACHCRB_DPTR_SHIFT;
|
||||
if (dptr == 0)
|
||||
dptr = desc->nchunks;
|
||||
dptr--;
|
||||
|
@ -1355,7 +1375,7 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
|
|||
}
|
||||
|
||||
/* Add the residue for the current chunk. */
|
||||
residue += rcar_dmac_chan_read(chan, RCAR_DMATCRB) << desc->xfer_shift;
|
||||
residue += tcrb << desc->xfer_shift;
|
||||
|
||||
return residue;
|
||||
}
|
||||
|
@ -1368,6 +1388,7 @@ static enum dma_status rcar_dmac_tx_status(struct dma_chan *chan,
|
|||
enum dma_status status;
|
||||
unsigned long flags;
|
||||
unsigned int residue;
|
||||
bool cyclic;
|
||||
|
||||
status = dma_cookie_status(chan, cookie, txstate);
|
||||
if (status == DMA_COMPLETE || !txstate)
|
||||
|
@ -1375,10 +1396,11 @@ static enum dma_status rcar_dmac_tx_status(struct dma_chan *chan,
|
|||
|
||||
spin_lock_irqsave(&rchan->lock, flags);
|
||||
residue = rcar_dmac_chan_get_residue(rchan, cookie);
|
||||
cyclic = rchan->desc.running ? rchan->desc.running->cyclic : false;
|
||||
spin_unlock_irqrestore(&rchan->lock, flags);
|
||||
|
||||
/* if there's no residue, the cookie is complete */
|
||||
if (!residue)
|
||||
if (!residue && !cyclic)
|
||||
return DMA_COMPLETE;
|
||||
|
||||
dma_set_residue(txstate, residue);
|
||||
|
|
Loading…
Reference in a new issue