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

Commit c014906a authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Paul Mundt
Browse files

dmaengine: shdma: extend .device_terminate_all() to record partial transfer



This patch extends the .device_terminate_all() method of the shdma driver
to return number of bytes transfered in the current descriptor.

Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent c8e3149b
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -10,6 +10,9 @@
#ifndef ASM_DMAENGINE_H
#define ASM_DMAENGINE_H

#include <linux/dmaengine.h>
#include <linux/list.h>

#include <asm/dma-register.h>

#define SH_DMAC_MAX_CHANNELS	6
@@ -70,4 +73,21 @@ struct sh_dmae_slave {
	struct sh_dmae_slave_config	*config;  /* Set by the driver */
};

struct sh_dmae_regs {
	u32 sar; /* SAR / source address */
	u32 dar; /* DAR / destination address */
	u32 tcr; /* TCR / transfer count */
};

struct sh_desc {
	struct sh_dmae_regs hw;
	struct list_head node;
	struct dma_async_tx_descriptor async_tx;
	enum dma_data_direction direction;
	dma_cookie_t cookie;
	size_t partial;
	int chunks;
	int mark;
};

#endif
+16 −0
Original line number Diff line number Diff line
@@ -587,6 +587,19 @@ static void sh_dmae_terminate_all(struct dma_chan *chan)
	if (!chan)
		return;

	dmae_halt(sh_chan);

	spin_lock_bh(&sh_chan->desc_lock);
	if (!list_empty(&sh_chan->ld_queue)) {
		/* Record partial transfer */
		struct sh_desc *desc = list_entry(sh_chan->ld_queue.next,
						  struct sh_desc, node);
		desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
			sh_chan->xmit_shift;

	}
	spin_unlock_bh(&sh_chan->desc_lock);

	sh_dmae_chan_ld_cleanup(sh_chan, true);
}

@@ -701,6 +714,9 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
	/* Find the first not transferred desciptor */
	list_for_each_entry(desc, &sh_chan->ld_queue, node)
		if (desc->mark == DESC_SUBMITTED) {
			dev_dbg(sh_chan->dev, "Queue #%d to %d: %u@%x -> %x\n",
				desc->async_tx.cookie, sh_chan->id,
				desc->hw.tcr, desc->hw.sar, desc->hw.dar);
			/* Get the ld start address from ld_queue */
			dmae_set_reg(sh_chan, &desc->hw);
			dmae_start(sh_chan);
+0 −16
Original line number Diff line number Diff line
@@ -21,22 +21,6 @@

#define SH_DMA_TCR_MAX 0x00FFFFFF	/* 16MB */

struct sh_dmae_regs {
	u32 sar; /* SAR / source address */
	u32 dar; /* DAR / destination address */
	u32 tcr; /* TCR / transfer count */
};

struct sh_desc {
	struct sh_dmae_regs hw;
	struct list_head node;
	struct dma_async_tx_descriptor async_tx;
	enum dma_data_direction direction;
	dma_cookie_t cookie;
	int chunks;
	int mark;
};

struct device;

struct sh_dmae_chan {