Commit c014906a870ce70e009def0c9d170ccabeb0be63
Committed by
Paul Mundt
1 parent
c8e3149ba7
Exists in
master
and in
7 other branches
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>
Showing 3 changed files with 36 additions and 16 deletions Side-by-side Diff
arch/sh/include/asm/dmaengine.h
... | ... | @@ -10,6 +10,9 @@ |
10 | 10 | #ifndef ASM_DMAENGINE_H |
11 | 11 | #define ASM_DMAENGINE_H |
12 | 12 | |
13 | +#include <linux/dmaengine.h> | |
14 | +#include <linux/list.h> | |
15 | + | |
13 | 16 | #include <asm/dma-register.h> |
14 | 17 | |
15 | 18 | #define SH_DMAC_MAX_CHANNELS 6 |
... | ... | @@ -68,6 +71,23 @@ |
68 | 71 | enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */ |
69 | 72 | struct device *dma_dev; /* Set by the platform */ |
70 | 73 | struct sh_dmae_slave_config *config; /* Set by the driver */ |
74 | +}; | |
75 | + | |
76 | +struct sh_dmae_regs { | |
77 | + u32 sar; /* SAR / source address */ | |
78 | + u32 dar; /* DAR / destination address */ | |
79 | + u32 tcr; /* TCR / transfer count */ | |
80 | +}; | |
81 | + | |
82 | +struct 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; | |
71 | 91 | }; |
72 | 92 | |
73 | 93 | #endif |
drivers/dma/shdma.c
... | ... | @@ -587,6 +587,19 @@ |
587 | 587 | if (!chan) |
588 | 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 | 603 | sh_dmae_chan_ld_cleanup(sh_chan, true); |
591 | 604 | } |
592 | 605 | |
... | ... | @@ -701,6 +714,9 @@ |
701 | 714 | /* Find the first not transferred desciptor */ |
702 | 715 | list_for_each_entry(desc, &sh_chan->ld_queue, node) |
703 | 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 | 720 | /* Get the ld start address from ld_queue */ |
705 | 721 | dmae_set_reg(sh_chan, &desc->hw); |
706 | 722 | dmae_start(sh_chan); |
drivers/dma/shdma.h
... | ... | @@ -21,22 +21,6 @@ |
21 | 21 | |
22 | 22 | #define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ |
23 | 23 | |
24 | -struct sh_dmae_regs { | |
25 | - u32 sar; /* SAR / source address */ | |
26 | - u32 dar; /* DAR / destination address */ | |
27 | - u32 tcr; /* TCR / transfer count */ | |
28 | -}; | |
29 | - | |
30 | -struct 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 | - | |
40 | 24 | struct device; |
41 | 25 | |
42 | 26 | struct sh_dmae_chan { |