Commit c014906a870ce70e009def0c9d170ccabeb0be63

Authored by Guennadi Liakhovetski
Committed by Paul Mundt
1 parent c8e3149ba7

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
... ... @@ -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);
... ... @@ -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 {