Commit 72a6e35d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 25cce03b 5bb5c3a3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;

+1 −1
Original line number Diff line number Diff line
@@ -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 */
+26 −4
Original line number Diff line number Diff line
@@ -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);