diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2013-01-09 03:17:14 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2013-01-09 09:30:59 -0500 |
commit | 21fe3c5245647d200a7ba25d42b80d21c578a8dc (patch) | |
tree | 2a79b7236dc49b3475558cb530d8f0844a6bf067 /drivers/dma | |
parent | f5c6a7df35b04db906577e90fa5e133e56433bcf (diff) |
dma: dw_dmac: add dwc_chan_pause and dwc_chan_resume
We will use at least the dwc_chan_resume() later.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/dw_dmac.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index d6b322a1f565..6c9e20a7ff51 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c | |||
@@ -988,6 +988,26 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) | |||
988 | return 0; | 988 | return 0; |
989 | } | 989 | } |
990 | 990 | ||
991 | static inline void dwc_chan_pause(struct dw_dma_chan *dwc) | ||
992 | { | ||
993 | u32 cfglo = channel_readl(dwc, CFG_LO); | ||
994 | |||
995 | channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP); | ||
996 | while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY)) | ||
997 | cpu_relax(); | ||
998 | |||
999 | dwc->paused = true; | ||
1000 | } | ||
1001 | |||
1002 | static inline void dwc_chan_resume(struct dw_dma_chan *dwc) | ||
1003 | { | ||
1004 | u32 cfglo = channel_readl(dwc, CFG_LO); | ||
1005 | |||
1006 | channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP); | ||
1007 | |||
1008 | dwc->paused = false; | ||
1009 | } | ||
1010 | |||
991 | static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | 1011 | static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, |
992 | unsigned long arg) | 1012 | unsigned long arg) |
993 | { | 1013 | { |
@@ -995,18 +1015,13 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | |||
995 | struct dw_dma *dw = to_dw_dma(chan->device); | 1015 | struct dw_dma *dw = to_dw_dma(chan->device); |
996 | struct dw_desc *desc, *_desc; | 1016 | struct dw_desc *desc, *_desc; |
997 | unsigned long flags; | 1017 | unsigned long flags; |
998 | u32 cfglo; | ||
999 | LIST_HEAD(list); | 1018 | LIST_HEAD(list); |
1000 | 1019 | ||
1001 | if (cmd == DMA_PAUSE) { | 1020 | if (cmd == DMA_PAUSE) { |
1002 | spin_lock_irqsave(&dwc->lock, flags); | 1021 | spin_lock_irqsave(&dwc->lock, flags); |
1003 | 1022 | ||
1004 | cfglo = channel_readl(dwc, CFG_LO); | 1023 | dwc_chan_pause(dwc); |
1005 | channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP); | ||
1006 | while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY)) | ||
1007 | cpu_relax(); | ||
1008 | 1024 | ||
1009 | dwc->paused = true; | ||
1010 | spin_unlock_irqrestore(&dwc->lock, flags); | 1025 | spin_unlock_irqrestore(&dwc->lock, flags); |
1011 | } else if (cmd == DMA_RESUME) { | 1026 | } else if (cmd == DMA_RESUME) { |
1012 | if (!dwc->paused) | 1027 | if (!dwc->paused) |
@@ -1014,9 +1029,7 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | |||
1014 | 1029 | ||
1015 | spin_lock_irqsave(&dwc->lock, flags); | 1030 | spin_lock_irqsave(&dwc->lock, flags); |
1016 | 1031 | ||
1017 | cfglo = channel_readl(dwc, CFG_LO); | 1032 | dwc_chan_resume(dwc); |
1018 | channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP); | ||
1019 | dwc->paused = false; | ||
1020 | 1033 | ||
1021 | spin_unlock_irqrestore(&dwc->lock, flags); | 1034 | spin_unlock_irqrestore(&dwc->lock, flags); |
1022 | } else if (cmd == DMA_TERMINATE_ALL) { | 1035 | } else if (cmd == DMA_TERMINATE_ALL) { |