]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/dma/dw/core.c
dmaengine: dw: don't perform DMA when dmaengine_submit is called
[karo-tx-linux.git] / drivers / dma / dw / core.c
index 7516be4677cf7e778ba3bef2482cae9179ff41a3..b0972b3869c730229bc91c9829c7ef625cc1ed35 100644 (file)
@@ -218,8 +218,10 @@ static inline void dwc_do_single_block(struct dw_dma_chan *dwc,
        struct dw_dma   *dw = to_dw_dma(dwc->chan.device);
        u32             ctllo;
 
-       /* Software emulation of LLP mode relies on interrupts to continue
-        * multi block transfer. */
+       /*
+        * Software emulation of LLP mode relies on interrupts to continue
+        * multi block transfer.
+        */
        ctllo = desc->lli.ctllo | DWC_CTLL_INT_EN;
 
        channel_writel(dwc, SAR, desc->lli.sar);
@@ -253,8 +255,7 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
                                                &dwc->flags);
                if (was_soft_llp) {
                        dev_err(chan2dev(&dwc->chan),
-                               "BUG: Attempted to start new LLP transfer "
-                               "inside ongoing one\n");
+                               "BUG: Attempted to start new LLP transfer inside ongoing one\n");
                        return;
                }
 
@@ -278,6 +279,15 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
        channel_set_bit(dw, CH_EN, dwc->mask);
 }
 
+static void dwc_dostart_first_queued(struct dw_dma_chan *dwc)
+{
+       if (list_empty(&dwc->queue))
+               return;
+
+       list_move(dwc->queue.next, &dwc->active_list);
+       dwc_dostart(dwc, dwc_first_active(dwc));
+}
+
 /*----------------------------------------------------------------------*/
 
 static void
@@ -334,10 +344,7 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
         * the completed ones.
         */
        list_splice_init(&dwc->active_list, &list);
-       if (!list_empty(&dwc->queue)) {
-               list_move(dwc->queue.next, &dwc->active_list);
-               dwc_dostart(dwc, dwc_first_active(dwc));
-       }
+       dwc_dostart_first_queued(dwc);
 
        spin_unlock_irqrestore(&dwc->lock, flags);
 
@@ -420,8 +427,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
                return;
        }
 
-       dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__,
-                       (unsigned long long)llp);
+       dev_vdbg(chan2dev(&dwc->chan), "%s: llp=%pad\n", __func__, &llp);
 
        list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
                /* Initial residue value */
@@ -467,10 +473,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
        /* Try to continue after resetting the channel... */
        dwc_chan_disable(dw, dwc);
 
-       if (!list_empty(&dwc->queue)) {
-               list_move(dwc->queue.next, &dwc->active_list);
-               dwc_dostart(dwc, dwc_first_active(dwc));
-       }
+       dwc_dostart_first_queued(dwc);
        spin_unlock_irqrestore(&dwc->lock, flags);
 }
 
@@ -567,9 +570,9 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
                        unlikely(status_xfer & dwc->mask)) {
                int i;
 
-               dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
-                               "interrupt, stopping DMA transfer\n",
-                               status_xfer ? "xfer" : "error");
+               dev_err(chan2dev(&dwc->chan),
+                       "cyclic DMA unexpected %s interrupt, stopping DMA transfer\n",
+                       status_xfer ? "xfer" : "error");
 
                spin_lock_irqsave(&dwc->lock, flags);
 
@@ -677,17 +680,9 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
         * possible, perhaps even appending to those already submitted
         * for DMA. But this is hard to do in a race-free manner.
         */
-       if (list_empty(&dwc->active_list)) {
-               dev_vdbg(chan2dev(tx->chan), "%s: started %u\n", __func__,
-                               desc->txd.cookie);
-               list_add_tail(&desc->desc_node, &dwc->active_list);
-               dwc_dostart(dwc, dwc_first_active(dwc));
-       } else {
-               dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", __func__,
-                               desc->txd.cookie);
 
-               list_add_tail(&desc->desc_node, &dwc->queue);
-       }
+       dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", __func__, desc->txd.cookie);
+       list_add_tail(&desc->desc_node, &dwc->queue);
 
        spin_unlock_irqrestore(&dwc->lock, flags);
 
@@ -711,9 +706,8 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
        u32                     ctllo;
 
        dev_vdbg(chan2dev(chan),
-                       "%s: d0x%llx s0x%llx l0x%zx f0x%lx\n", __func__,
-                       (unsigned long long)dest, (unsigned long long)src,
-                       len, flags);
+                       "%s: d%pad s%pad l0x%zx f0x%lx\n", __func__,
+                       &dest, &src, len, flags);
 
        if (unlikely(!len)) {
                dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
@@ -1093,9 +1087,12 @@ dwc_tx_status(struct dma_chan *chan,
 static void dwc_issue_pending(struct dma_chan *chan)
 {
        struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
+       unsigned long           flags;
 
-       if (!list_empty(&dwc->queue))
-               dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
+       spin_lock_irqsave(&dwc->lock, flags);
+       if (list_empty(&dwc->active_list))
+               dwc_dostart_first_queued(dwc);
+       spin_unlock_irqrestore(&dwc->lock, flags);
 }
 
 static int dwc_alloc_chan_resources(struct dma_chan *chan)
@@ -1401,9 +1398,9 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
        /* Let's make a cyclic list */
        last->lli.llp = cdesc->desc[0]->txd.phys;
 
-       dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu "
-                       "period %zu periods %d\n", (unsigned long long)buf_addr,
-                       buf_len, period_len, periods);
+       dev_dbg(chan2dev(&dwc->chan),
+                       "cyclic prepared buf %pad len %zu period %zu periods %d\n",
+                       &buf_addr, buf_len, period_len, periods);
 
        cdesc->periods = periods;
        dwc->cdesc = cdesc;
@@ -1546,11 +1543,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
        /* Disable BLOCK interrupts as well */
        channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
 
-       err = devm_request_irq(chip->dev, chip->irq, dw_dma_interrupt,
-                              IRQF_SHARED, "dw_dmac", dw);
-       if (err)
-               return err;
-
        /* Create a pool of consistent memory blocks for hardware descriptors */
        dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", chip->dev,
                                         sizeof(struct dw_desc), 4, 0);
@@ -1561,6 +1553,11 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
 
        tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
 
+       err = request_irq(chip->irq, dw_dma_interrupt, IRQF_SHARED,
+                         "dw_dmac", dw);
+       if (err)
+               return err;
+
        INIT_LIST_HEAD(&dw->dma.channels);
        for (i = 0; i < nr_channels; i++) {
                struct dw_dma_chan      *dwc = &dw->chan[i];
@@ -1603,9 +1600,11 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
                        dev_dbg(chip->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
                                           dwc_params);
 
-                       /* Decode maximum block size for given channel. The
+                       /*
+                        * Decode maximum block size for given channel. The
                         * stored 4 bit value represents blocks from 0x00 for 3
-                        * up to 0x0a for 4095. */
+                        * up to 0x0a for 4095.
+                        */
                        dwc->block_size =
                                (4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
                        dwc->nollp =
@@ -1663,6 +1662,7 @@ int dw_dma_remove(struct dw_dma_chip *chip)
        dw_dma_off(dw);
        dma_async_device_unregister(&dw->dma);
 
+       free_irq(chip->irq, dw);
        tasklet_kill(&dw->tasklet);
 
        list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels,