summaryrefslogtreecommitdiff
path: root/drivers/dma
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-02 11:45:42 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-02 11:45:42 -0700
commit0a276d1675bc1b8de3ba269ba64b8f3e288d8309 (patch)
treeff552f58874b245f5962487ef53ce27ebcda5857 /drivers/dma
parent25aa6a7ae46c6a041c46a2d314b9ab7c4f2baa41 (diff)
parent08298f0612e5e369d1da89b92cac5d2c71ddb9af (diff)
Merge tag 'sh-for-linus' of git://github.com/pmundt/linux-sh
Pull SuperH fixes from Paul Mundt. * tag 'sh-for-linus' of git://github.com/pmundt/linux-sh: (24 commits) sh: explicitly include sh_dma.h in setup-sh7722.c sh: ecovec: care CN5 VBUS if USB host mode sh: sh7724: fixup renesas_usbhs clock settings sh: intc: initial irqdomain support. sh: pfc: Fix up init ordering mess. serial: sh-sci: fix compilation breakage, when DMA is enabled dmaengine: shdma: restore partial transfer calculation sh: modify the sh_dmae_slave_config for RSPI in setup-sh7757 sh: Fix up recursive fault in oops with unset TTB. sh: pfc: Build fix for pinctrl_remove_gpio_range() changes. sh: select the fixed regulator driver on several boards sh: ecovec: switch MMC power control to regulators sh: add fixed voltage regulators to se7724 sh: add fixed voltage regulators to sdk7786 sh: add fixed voltage regulators to rsk sh: add fixed voltage regulators to migor sh: add fixed voltage regulators to kfr2r09 sh: add fixed voltage regulators to ap325rxa sh: add fixed voltage regulators to sh7757lcr sh: add fixed voltage regulators to sh2007 ...
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/sh/shdma-base.c9
-rw-r--r--drivers/dma/sh/shdma.c12
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
index 27f5c781fd73..f4cd946d259d 100644
--- a/drivers/dma/sh/shdma-base.c
+++ b/drivers/dma/sh/shdma-base.c
@@ -483,6 +483,7 @@ static struct shdma_desc *shdma_add_desc(struct shdma_chan *schan,
new->mark = DESC_PREPARED;
new->async_tx.flags = flags;
new->direction = direction;
+ new->partial = 0;
*len -= copy_size;
if (direction == DMA_MEM_TO_MEM || direction == DMA_MEM_TO_DEV)
@@ -644,6 +645,14 @@ static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
case DMA_TERMINATE_ALL:
spin_lock_irqsave(&schan->chan_lock, flags);
ops->halt_channel(schan);
+
+ if (ops->get_partial && !list_empty(&schan->ld_queue)) {
+ /* Record partial transfer */
+ struct shdma_desc *desc = list_first_entry(&schan->ld_queue,
+ struct shdma_desc, node);
+ desc->partial = ops->get_partial(schan, desc);
+ }
+
spin_unlock_irqrestore(&schan->chan_lock, flags);
shdma_chan_ld_cleanup(schan, true);
diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
index 027c9be97654..f41bcc5267fd 100644
--- a/drivers/dma/sh/shdma.c
+++ b/drivers/dma/sh/shdma.c
@@ -381,6 +381,17 @@ static bool sh_dmae_chan_irq(struct shdma_chan *schan, int irq)
return true;
}
+static size_t sh_dmae_get_partial(struct shdma_chan *schan,
+ struct shdma_desc *sdesc)
+{
+ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
+ shdma_chan);
+ struct sh_dmae_desc *sh_desc = container_of(sdesc,
+ struct sh_dmae_desc, shdma_desc);
+ return (sh_desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
+ sh_chan->xmit_shift;
+}
+
/* Called from error IRQ or NMI */
static bool sh_dmae_reset(struct sh_dmae_device *shdev)
{
@@ -632,6 +643,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = {
.start_xfer = sh_dmae_start_xfer,
.embedded_desc = sh_dmae_embedded_desc,
.chan_irq = sh_dmae_chan_irq,
+ .get_partial = sh_dmae_get_partial,
};
static int __devinit sh_dmae_probe(struct platform_device *pdev)