mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
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>
This commit is contained in:
parent
c8e3149ba7
commit
c014906a87
3 changed files with 36 additions and 16 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue