]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dmaengine: dw: fix cyclic transfer setup
authorMans Rullgard <mans@mansr.com>
Mon, 11 Jan 2016 13:04:28 +0000 (13:04 +0000)
committerLuis Henriques <luis.henriques@canonical.com>
Tue, 2 Feb 2016 19:09:37 +0000 (19:09 +0000)
commit df3bb8a0e619d501cd13334c3e0586edcdcbc716 upstream.

Commit 61e183f83069 ("dmaengine/dw_dmac: Reconfigure interrupt and
chan_cfg register on resume") moved some channel initialisation to
a new function which must be called before starting a transfer.

This updates dw_dma_cyclic_start() to use dwc_dostart() like the other
modes, thus ensuring dwc_initialize() gets called and removing some code
duplication.

Fixes: 61e183f83069 ("dmaengine/dw_dmac: Reconfigure interrupt and chan_cfg register on resume")
Signed-off-by: Mans Rullgard <mans@mansr.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
drivers/dma/dw/core.c

index b37d58f4cc93c1e52a4dde8d624899ed862d4b5f..9ce8d5eda1c30e19d3d8325628ded4afc7ecbcd2 100644 (file)
@@ -1206,7 +1206,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
 int dw_dma_cyclic_start(struct dma_chan *chan)
 {
        struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
-       struct dw_dma           *dw = to_dw_dma(dwc->chan.device);
        unsigned long           flags;
 
        if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
@@ -1215,26 +1214,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan)
        }
 
        spin_lock_irqsave(&dwc->lock, flags);
-
-       /* Assert channel is idle */
-       if (dma_readl(dw, CH_EN) & dwc->mask) {
-               dev_err(chan2dev(&dwc->chan),
-                       "BUG: Attempted to start non-idle channel\n");
-               dwc_dump_chan_regs(dwc);
-               spin_unlock_irqrestore(&dwc->lock, flags);
-               return -EBUSY;
-       }
-
-       dma_writel(dw, CLEAR.ERROR, dwc->mask);
-       dma_writel(dw, CLEAR.XFER, dwc->mask);
-
-       /* Setup DMAC channel registers */
-       channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
-       channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
-       channel_writel(dwc, CTL_HI, 0);
-
-       channel_set_bit(dw, CH_EN, dwc->mask);
-
+       dwc_dostart(dwc, dwc->cdesc->desc[0]);
        spin_unlock_irqrestore(&dwc->lock, flags);
 
        return 0;