Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b08284b authored by Jassi Brar's avatar Jassi Brar Committed by Ben Dooks
Browse files

ARM: S3C64XX: DMA: Callback with correct buffer pointer



buffdone callback should be called per buffer request with pointer
to the latest serviced request.
'next' should point to the one next to currently active.

Signed-off-by: default avatarJassi Brar <jassi.brar@samsung.com>
Signed-off-by: default avatarBen Dooks <ben-linux@fluff.org>
parent 7507f39c
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -576,6 +576,7 @@ static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
	errstat = readl(dmac->regs + PL080_ERR_STATUS);

	for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
		struct s3c64xx_dma_buff *buff;

		if (!(errstat & bit) && !(tcstat & bit))
			continue;
@@ -591,7 +592,33 @@ static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
		if (errstat & bit)
			writel(bit, dmac->regs + PL080_ERR_CLEAR);

		s3c64xx_dma_bufffdone(chan, chan->curr, res);
		/* 'next' points to the buffer that is next to the
		 * currently active buffer.
		 * For CIRCULAR queues, 'next' will be same as 'curr'
		 * when 'end' is the active buffer.
		 */
		buff = chan->curr;
		while (buff && buff != chan->next
				&& buff->next != chan->next)
			buff = buff->next;

		if (!buff)
			BUG();

		if (buff == chan->next)
			buff = chan->end;

		s3c64xx_dma_bufffdone(chan, buff, res);

		/* Update 'next' */
		buff = chan->next;
		if (chan->next == chan->end) {
			chan->next = chan->curr;
			if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
				chan->end = NULL;
		} else {
			chan->next = buff->next;
		}
	}

	return IRQ_HANDLED;