diff options
| author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2010-02-18 11:30:02 -0500 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2010-03-01 21:12:03 -0500 |
| commit | c014906a870ce70e009def0c9d170ccabeb0be63 (patch) | |
| tree | b1cfb6520ed0bcdfb0f1b32282b94658a989b04f | |
| parent | c8e3149ba7de24dfd4c37bb0df23c878cdecd8d4 (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.h | 20 | ||||
| -rw-r--r-- | drivers/dma/shdma.c | 16 | ||||
| -rw-r--r-- | drivers/dma/shdma.h | 16 |
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 | ||
| 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; | ||
| 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 | ||
| 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 | struct device; | 24 | struct device; |
| 41 | 25 | ||
| 42 | struct sh_dmae_chan { | 26 | struct sh_dmae_chan { |
