]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
Merge branch 'dw_dmac' into dmaengine
authorDan Williams <dan.j.williams@intel.com>
Mon, 14 Feb 2011 11:36:51 +0000 (03:36 -0800)
committerDan Williams <dan.j.williams@intel.com>
Mon, 14 Feb 2011 11:36:51 +0000 (03:36 -0800)
arch/avr32/mach-at32ap/at32ap700x.c
drivers/dma/dw_dmac.c
include/linux/dw_dmac.h

index e67c999454284f46dee1c3ba0742cbbe0221ba23..2747cde8c9a7102d378c738d82a1e50db8ce879a 100644 (file)
@@ -2048,6 +2048,8 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
                rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
                rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3);
                rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+               rx_dws->src_master = 0;
+               rx_dws->dst_master = 1;
        }
 
        /* Check if DMA slave interface for playback should be configured. */
@@ -2056,6 +2058,8 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
                tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
                tx_dws->cfg_hi = DWC_CFGH_DST_PER(4);
                tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+               rx_dws->src_master = 0;
+               rx_dws->dst_master = 1;
        }
 
        if (platform_device_add_data(pdev, data,
@@ -2128,6 +2132,8 @@ at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data)
        dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
        dws->cfg_hi = DWC_CFGH_DST_PER(2);
        dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+       dws->src_master = 0;
+       dws->dst_master = 1;
 
        if (platform_device_add_data(pdev, data,
                                sizeof(struct atmel_abdac_pdata)))
index a3991ab0d67e06cf6e99d41d9a1a923109dc1a06..08dab3badad2db79605e3dba0f82d3fc94f0923b 100644 (file)
  * which does not support descriptor writeback.
  */
 
-/* NOTE:  DMS+SMS is system-specific. We should get this information
- * from the platform code somehow.
- */
-#define DWC_DEFAULT_CTLLO      (DWC_CTLL_DST_MSIZE(0)          \
-                               | DWC_CTLL_SRC_MSIZE(0)         \
-                               | DWC_CTLL_DMS(0)               \
-                               | DWC_CTLL_SMS(1)               \
-                               | DWC_CTLL_LLP_D_EN             \
-                               | DWC_CTLL_LLP_S_EN)
+#define DWC_DEFAULT_CTLLO(private) ({                          \
+               struct dw_dma_slave *__slave = (private);       \
+               int dms = __slave ? __slave->dst_master : 0;    \
+               int sms = __slave ? __slave->src_master : 1;    \
+                                                               \
+               (DWC_CTLL_DST_MSIZE(0)                          \
+                | DWC_CTLL_SRC_MSIZE(0)                        \
+                | DWC_CTLL_LLP_D_EN                            \
+                | DWC_CTLL_LLP_S_EN                            \
+                | DWC_CTLL_DMS(dms)                            \
+                | DWC_CTLL_SMS(sms));                          \
+       })
 
 /*
  * This is configuration-dependent and usually a funny size like 4095.
@@ -291,6 +294,9 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
                return;
        }
 
+       if (list_empty(&dwc->active_list))
+               return;
+
        dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp);
 
        list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
@@ -588,7 +594,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
        else
                src_width = dst_width = 0;
 
-       ctllo = DWC_DEFAULT_CTLLO
+       ctllo = DWC_DEFAULT_CTLLO(chan->private)
                        | DWC_CTLL_DST_WIDTH(dst_width)
                        | DWC_CTLL_SRC_WIDTH(src_width)
                        | DWC_CTLL_DST_INC
@@ -669,7 +675,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
        switch (direction) {
        case DMA_TO_DEVICE:
-               ctllo = (DWC_DEFAULT_CTLLO
+               ctllo = (DWC_DEFAULT_CTLLO(chan->private)
                                | DWC_CTLL_DST_WIDTH(reg_width)
                                | DWC_CTLL_DST_FIX
                                | DWC_CTLL_SRC_INC
@@ -714,7 +720,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                }
                break;
        case DMA_FROM_DEVICE:
-               ctllo = (DWC_DEFAULT_CTLLO
+               ctllo = (DWC_DEFAULT_CTLLO(chan->private)
                                | DWC_CTLL_SRC_WIDTH(reg_width)
                                | DWC_CTLL_DST_INC
                                | DWC_CTLL_SRC_FIX
@@ -1126,7 +1132,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
                case DMA_TO_DEVICE:
                        desc->lli.dar = dws->tx_reg;
                        desc->lli.sar = buf_addr + (period_len * i);
-                       desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+                       desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan->private)
                                        | DWC_CTLL_DST_WIDTH(reg_width)
                                        | DWC_CTLL_SRC_WIDTH(reg_width)
                                        | DWC_CTLL_DST_FIX
@@ -1137,7 +1143,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
                case DMA_FROM_DEVICE:
                        desc->lli.dar = buf_addr + (period_len * i);
                        desc->lli.sar = dws->rx_reg;
-                       desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+                       desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan->private)
                                        | DWC_CTLL_SRC_WIDTH(reg_width)
                                        | DWC_CTLL_DST_WIDTH(reg_width)
                                        | DWC_CTLL_DST_INC
@@ -1335,6 +1341,8 @@ static int __init dw_probe(struct platform_device *pdev)
 
        dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
        dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
+       if (pdata->is_private)
+               dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask);
        dw->dma.dev = &pdev->dev;
        dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
        dw->dma.device_free_chan_resources = dwc_free_chan_resources;
index c8aad713a0460bd1c66c0962f930602501b2f9e7..deec66b37180cf63d132eab997c45483be991d6a 100644 (file)
 /**
  * struct dw_dma_platform_data - Controller configuration parameters
  * @nr_channels: Number of channels supported by hardware (max 8)
+ * @is_private: The device channels should be marked as private and not for
+ *     by the general purpose DMA channel allocator.
  */
 struct dw_dma_platform_data {
        unsigned int    nr_channels;
+       bool            is_private;
 };
 
 /**
@@ -52,6 +55,8 @@ struct dw_dma_slave {
        enum dw_dma_slave_width reg_width;
        u32                     cfg_hi;
        u32                     cfg_lo;
+       int                     src_master;
+       int                     dst_master;
 };
 
 /* Platform-configurable bits in CFG_HI */