dma: dw_dmac: add dwc_chan_pause and dwc_chan_resume
PATCH 1/2 dma: dw_dmac: add dwc_chan_pause and dwc_chan_resume
We will use at least the dwc_chan_resume() later.
--- drivers/dma/dw_dmac.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
drivers/dma/dw_dmac.c +22 -9
@@ -1008,6 +1008,26 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)return 0 ; } +static inline void dwc_chan_pause (struct dw_dma_chan *dwc) +{ +u32 cfglo =channel_readl (dwc,CFG_LO ); + +channel_writel (dwc,CFG_LO , cfglo |DWC_CFGL_CH_SUSP ); +while (!(channel_readl (dwc,CFG_LO ) &DWC_CFGL_FIFO_EMPTY )) +cpu_relax (); + + dwc->paused = true; +} + +static inline void dwc_chan_resume (struct dw_dma_chan *dwc) +{ +u32 cfglo =channel_readl (dwc,CFG_LO ); + +channel_writel (dwc,CFG_LO , cfglo & ~DWC_CFGL_CH_SUSP ); + + dwc->paused = false; +} +static int dwc_control (struct dma_chan *chan,enum dma_ctrl_cmd cmd,unsigned long arg) {
@@ -1015,18 +1035,13 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,struct dw_dma *dw =to_dw_dma (chan->device);struct dw_desc *desc, *_desc;unsigned long flags; -u32 cfglo;LIST_HEAD (list);if (cmd ==DMA_PAUSE ) {spin_lock_irqsave (&dwc->lock, flags); - cfglo =channel_readl (dwc,CFG_LO ); -channel_writel (dwc,CFG_LO , cfglo |DWC_CFGL_CH_SUSP ); -while (!(channel_readl (dwc,CFG_LO ) &DWC_CFGL_FIFO_EMPTY )) -cpu_relax (); +dwc_chan_pause (dwc); - dwc->paused = true;spin_unlock_irqrestore (&dwc->lock, flags); }else if (cmd ==DMA_RESUME ) {if (!dwc->paused)
@@ -1034,9 +1049,7 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,spin_lock_irqsave (&dwc->lock, flags); - cfglo =channel_readl (dwc,CFG_LO ); -channel_writel (dwc,CFG_LO , cfglo & ~DWC_CFGL_CH_SUSP ); - dwc->paused = false; +dwc_chan_resume (dwc);spin_unlock_irqrestore (&dwc->lock, flags); }else if (cmd ==DMA_TERMINATE_ALL ) {
Signature · 1 line
1.7.10.4
PATCH 2/2 dma: dw_dmac: clear suspend during termination
From: Heikki Krogerus <[email protected]>
Clear DWC_CFGL_CH_SUSP bit during termination if the channel was paused.
--- drivers/dma/dw_dmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/dw_dmac.c +1 -1
@@ -1059,7 +1059,7 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,dwc_chan_disable (dw, dwc); - dwc->paused = false; +dwc_chan_resume (dwc);/* active_list entries will end up before queued entries */ list_splice_init (&dwc->queue, &list);
Signature · 1 line
1.7.10.4
Re: [PATCH 2/2] dma: dw_dmac: clear suspend during termination
Quoted 7 lines · Andy Shevchenko
From: Heikki Krogerus <[email protected]>
Clear
DWC_CFGL_CH_SUSPbit during termination if the channel was paused.Signed-off-by Heikki Krogerus <[email protected]>Signed-off-by Andy Shevchenko <[email protected]>
Insufficient commit log :(
You don't have to say here, what you are doing, but why you are doing it.
Please mention the reason here first, then repost the series after getting my comments
--
viresh
Re: [PATCH 2/2] dma: dw_dmac: clear suspend during termination
Quoted 4 lines · Viresh Kumar
Quoted 2 lines · Andy Shevchenko
From: Heikki Krogerus <[email protected]>
Quoted 8 lines
Quoted 5 lines
Clear
DWC_CFGL_CH_SUSPbit during termination if the channel was paused.Signed-off-by Heikki Krogerus <[email protected]>Signed-off-by Andy Shevchenko <[email protected]>Insufficient commit log :(
You don't have to say here, what you are doing, but why you are doing it.
Fighting against bug. The workflow in our case is to a) pause the dma,
b) do something in the slave driver, c) terminate all transfers, d) submit new transfer. But d) doesn't happen because the channel is still paused.
Quoted 2 lines
Please mention the reason here first, then repost the series after getting my comments
Okay.
Signature · 2 lines
Andy Shevchenko <[email protected]> Intel Finland Oy
Quoted 3 lines · Andy Shevchenko
We will use at least the
dwc_chan_resume()later.Signed-off-by Andy Shevchenko <[email protected]>
For both patches:
Just fix the logs and repost with my Acks.