dmaengine: dw: apply both HS interfaces and remove slave_id usage
[firefly-linux-kernel-4.4.55.git] / drivers / dma / dw / core.c
index a27ded53ab4f0e5eb2fa312e891da3adf8a49ef9..1c4521283fa9c0b6ea3957050fbc50b5302bcd97 100644 (file)
  * support descriptor writeback.
  */
 
-static inline bool is_request_line_unset(struct dw_dma_chan *dwc)
-{
-       return dwc->request_line == (typeof(dwc->request_line))~0;
-}
-
-static inline void dwc_set_masters(struct dw_dma_chan *dwc)
-{
-       struct dw_dma *dw = to_dw_dma(dwc->chan.device);
-       struct dw_dma_slave *dws = dwc->chan.private;
-       unsigned char mmax = dw->nr_masters - 1;
-
-       if (!is_request_line_unset(dwc))
-               return;
-
-       dwc->src_master = min_t(unsigned char, mmax, dwc_get_sms(dws));
-       dwc->dst_master = min_t(unsigned char, mmax, dwc_get_dms(dws));
-}
-
 #define DWC_DEFAULT_CTLLO(_chan) ({                            \
                struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan);       \
                struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \
@@ -155,13 +137,11 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
                 */
                BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
 
-               cfghi = dws->cfg_hi;
-               cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK;
+               cfghi |= DWC_CFGH_DST_PER(dws->dst_id);
+               cfghi |= DWC_CFGH_SRC_PER(dws->src_id);
        } else {
-               if (dwc->direction == DMA_MEM_TO_DEV)
-                       cfghi = DWC_CFGH_DST_PER(dwc->request_line);
-               else if (dwc->direction == DMA_DEV_TO_MEM)
-                       cfghi = DWC_CFGH_SRC_PER(dwc->request_line);
+               cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
+               cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
        }
 
        channel_writel(dwc, CFG_LO, cfglo);
@@ -279,6 +259,19 @@ 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)
+{
+       struct dw_desc *desc;
+
+       if (list_empty(&dwc->queue))
+               return;
+
+       list_move(dwc->queue.next, &dwc->active_list);
+       desc = dwc_first_active(dwc);
+       dev_vdbg(chan2dev(&dwc->chan), "%s: started %u\n", __func__, desc->txd.cookie);
+       dwc_dostart(dwc, desc);
+}
+
 /*----------------------------------------------------------------------*/
 
 static void
@@ -335,10 +328,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);
 
@@ -467,10 +457,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);
 }
 
@@ -677,17 +664,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);
 
@@ -968,10 +947,6 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
        memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
        dwc->direction = sconfig->direction;
 
-       /* Take the request line from slave_id member */
-       if (is_request_line_unset(dwc))
-               dwc->request_line = sconfig->slave_id;
-
        convert_burst(&dwc->dma_sconfig.src_maxburst);
        convert_burst(&dwc->dma_sconfig.dst_maxburst);
 
@@ -1092,9 +1067,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)
@@ -1121,8 +1099,6 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
         * doesn't mean what you think it means), and status writeback.
         */
 
-       dwc_set_masters(dwc);
-
        spin_lock_irqsave(&dwc->lock, flags);
        i = dwc->descs_allocated;
        while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) {
@@ -1180,7 +1156,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
        list_splice_init(&dwc->free_list, &list);
        dwc->descs_allocated = 0;
        dwc->initialized = false;
-       dwc->request_line = ~0;
 
        /* Disable interrupts */
        channel_clear_bit(dw, MASK.XFER, dwc->mask);
@@ -1602,7 +1577,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
                channel_clear_bit(dw, CH_EN, dwc->mask);
 
                dwc->direction = DMA_TRANS_NONE;
-               dwc->request_line = ~0;
 
                /* Hardware configuration */
                if (autocfg) {