aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2010-02-18 11:30:02 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-03-01 21:12:03 -0500
commitc014906a870ce70e009def0c9d170ccabeb0be63 (patch)
treeb1cfb6520ed0bcdfb0f1b32282b94658a989b04f
parentc8e3149ba7de24dfd4c37bb0df23c878cdecd8d4 (diff)
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: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/include/asm/dmaengine.h20
-rw-r--r--drivers/dma/shdma.c16
-rw-r--r--drivers/dma/shdma.h16
3 files changed, 36 insertions, 16 deletions
diff --git a/arch/sh/include/asm/dmaengine.h b/arch/sh/include/asm/dmaengine.h
index 9586e4a482b1..bf2f30cf0a27 100644
--- a/arch/sh/include/asm/dmaengine.h
+++ b/arch/sh/include/asm/dmaengine.h
@@ -10,6 +10,9 @@
10#ifndef ASM_DMAENGINE_H 10#ifndef ASM_DMAENGINE_H
11#define ASM_DMAENGINE_H 11#define ASM_DMAENGINE_H
12 12
13#include <linux/dmaengine.h>
14#include <linux/list.h>
15
13#include <asm/dma-register.h> 16#include <asm/dma-register.h>
14 17
15#define SH_DMAC_MAX_CHANNELS 6 18#define SH_DMAC_MAX_CHANNELS 6
@@ -70,4 +73,21 @@ struct sh_dmae_slave {
70 struct sh_dmae_slave_config *config; /* Set by the driver */ 73 struct sh_dmae_slave_config *config; /* Set by the driver */
71}; 74};
72 75
76struct sh_dmae_regs {
77 u32 sar; /* SAR / source address */
78 u32 dar; /* DAR / destination address */
79 u32 tcr; /* TCR / transfer count */
80};
81
82struct sh_desc {
83 struct sh_dmae_regs hw;
84 struct list_head node;
85 struct dma_async_tx_descriptor async_tx;
86 enum dma_data_direction direction;
87 dma_cookie_t cookie;
88 size_t partial;
89 int chunks;
90 int mark;
91};
92
73#endif 93#endif
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index ea6779f3e73f..5d17e09cb625 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -587,6 +587,19 @@ static void sh_dmae_terminate_all(struct dma_chan *chan)
587 if (!chan) 587 if (!chan)
588 return; 588 return;
589 589
590 dmae_halt(sh_chan);
591
592 spin_lock_bh(&sh_chan->desc_lock);
593 if (!list_empty(&sh_chan->ld_queue)) {
594 /* Record partial transfer */
595 struct sh_desc *desc = list_entry(sh_chan->ld_queue.next,
596 struct sh_desc, node);
597 desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
598 sh_chan->xmit_shift;
599
600 }
601 spin_unlock_bh(&sh_chan->desc_lock);
602
590 sh_dmae_chan_ld_cleanup(sh_chan, true); 603 sh_dmae_chan_ld_cleanup(sh_chan, true);
591} 604}
592 605
@@ -701,6 +714,9 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
701 /* Find the first not transferred desciptor */ 714 /* Find the first not transferred desciptor */
702 list_for_each_entry(desc, &sh_chan->ld_queue, node) 715 list_for_each_entry(desc, &sh_chan->ld_queue, node)
703 if (desc->mark == DESC_SUBMITTED) { 716 if (desc->mark == DESC_SUBMITTED) {
717 dev_dbg(sh_chan->dev, "Queue #%d to %d: %u@%x -> %x\n",
718 desc->async_tx.cookie, sh_chan->id,
719 desc->hw.tcr, desc->hw.sar, desc->hw.dar);
704 /* Get the ld start address from ld_queue */ 720 /* Get the ld start address from ld_queue */
705 dmae_set_reg(sh_chan, &desc->hw); 721 dmae_set_reg(sh_chan, &desc->hw);
706 dmae_start(sh_chan); 722 dmae_start(sh_chan);
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index 9f0897f7fe34..153609a1e96c 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -21,22 +21,6 @@
21 21
22#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ 22#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */
23 23
24struct sh_dmae_regs {
25 u32 sar; /* SAR / source address */
26 u32 dar; /* DAR / destination address */
27 u32 tcr; /* TCR / transfer count */
28};
29
30struct sh_desc {
31 struct sh_dmae_regs hw;
32 struct list_head node;
33 struct dma_async_tx_descriptor async_tx;
34 enum dma_data_direction direction;
35 dma_cookie_t cookie;
36 int chunks;
37 int mark;
38};
39
40struct device; 24struct device;
41 25
42struct sh_dmae_chan { 26struct sh_dmae_chan {