]> git.openfabrics.org - ~emulex/infiniband.git/commitdiff
dmaengine: dw: introduce generic filter function
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tue, 19 Aug 2014 17:29:16 +0000 (20:29 +0300)
committerVinod Koul <vinod.koul@intel.com>
Thu, 11 Sep 2014 06:18:13 +0000 (11:48 +0530)
The introduced filter function would be reused in the ACPI and DT cases since
in those cases we have to apply mandatory data to the requested channel. Thus,
patch moves platform driver to use it in that case.

The function unlikely can't be used by users of the driver due to an implicit
dependency to the dw_dmac_core module.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
drivers/dma/dw/core.c
drivers/dma/dw/internal.h
drivers/dma/dw/platform.c

index 1c4521283fa9c0b6ea3957050fbc50b5302bcd97..10e43eae61a789d59424ee27b7e84d5d36c7bf8e 100644 (file)
@@ -919,6 +919,26 @@ err_desc_get:
        return NULL;
 }
 
+bool dw_dma_filter(struct dma_chan *chan, void *param)
+{
+       struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+       struct dw_dma_slave *dws = param;
+
+       if (!dws || dws->dma_dev != chan->device->dev)
+               return false;
+
+       /* We have to copy data since dws can be temporary storage */
+
+       dwc->src_id = dws->src_id;
+       dwc->dst_id = dws->dst_id;
+
+       dwc->src_master = dws->src_master;
+       dwc->dst_master = dws->dst_master;
+
+       return true;
+}
+EXPORT_SYMBOL_GPL(dw_dma_filter);
+
 /*
  * Fix sconfig's burst size according to dw_dmac. We need to convert them as:
  * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
index 43cc1dfad5c9ffbe76cd23559bb6dd262a9684c8..2c8d02f527374785a29d74336b4e7052a46bfcbe 100644 (file)
@@ -43,28 +43,6 @@ int dw_dma_resume(struct dw_dma_chip *chip);
 
 #endif /* CONFIG_PM_SLEEP */
 
-/**
- * dwc_get_dms - get destination master
- * @slave:     pointer to the custom slave configuration
- *
- * Returns destination master in the custom slave configuration if defined, or
- * default value otherwise.
- */
-static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
-{
-       return slave ? slave->dst_master : 0;
-}
-
-/**
- * dwc_get_sms - get source master
- * @slave:     pointer to the custom slave configuration
- *
- * Returns source master in the custom slave configuration if defined, or
- * default value otherwise.
- */
-static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
-{
-       return slave ? slave->src_master : 1;
-}
+extern bool dw_dma_filter(struct dma_chan *chan, void *param);
 
 #endif /* _DW_DMAC_INTERNAL_H */
index 7aa3cd33fdec80acd6820c7ae6585b6d9c60bcab..860c9acf3feff2777cb9a01000feb6db30bc651a 100644 (file)
 
 #include "internal.h"
 
-struct dw_dma_of_filter_args {
-       struct dw_dma *dw;
-       unsigned int req;
-       unsigned int src;
-       unsigned int dst;
-};
-
-static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
-{
-       struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
-       struct dw_dma_of_filter_args *fargs = param;
-
-       /* Ensure the device matches our channel */
-       if (chan->device != &fargs->dw->dma)
-               return false;
-
-       dwc->src_id = fargs->req;
-       dwc->dst_id = fargs->req;
-       dwc->src_master = fargs->src;
-       dwc->dst_master = fargs->dst;
-
-       return true;
-}
-
 static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
                                        struct of_dma *ofdma)
 {
        struct dw_dma *dw = ofdma->of_dma_data;
-       struct dw_dma_of_filter_args fargs = {
-               .dw = dw,
+       struct dw_dma_slave slave = {
+               .dma_dev = dw->dma.dev,
        };
        dma_cap_mask_t cap;
 
        if (dma_spec->args_count != 3)
                return NULL;
 
-       fargs.req = dma_spec->args[0];
-       fargs.src = dma_spec->args[1];
-       fargs.dst = dma_spec->args[2];
+       slave.src_id = dma_spec->args[0];
+       slave.dst_id = dma_spec->args[0];
+       slave.src_master = dma_spec->args[1];
+       slave.dst_master = dma_spec->args[2];
 
-       if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
-                   fargs.src >= dw->nr_masters ||
-                   fargs.dst >= dw->nr_masters))
+       if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS ||
+                   slave.dst_id >= DW_DMA_MAX_NR_REQUESTS ||
+                   slave.src_master >= dw->nr_masters ||
+                   slave.dst_master >= dw->nr_masters))
                return NULL;
 
        dma_cap_zero(cap);
        dma_cap_set(DMA_SLAVE, cap);
 
        /* TODO: there should be a simpler way to do this */
-       return dma_request_channel(cap, dw_dma_of_filter, &fargs);
+       return dma_request_channel(cap, dw_dma_filter, &slave);
 }
 
 #ifdef CONFIG_ACPI
 static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
 {
-       struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
        struct acpi_dma_spec *dma_spec = param;
+       struct dw_dma_slave slave = {
+               .dma_dev = dma_spec->dev,
+               .src_id = dma_spec->slave_id,
+               .dst_id = dma_spec->slave_id,
+               .src_master = 1,
+               .dst_master = 0,
+       };
 
-       if (chan->device->dev != dma_spec->dev ||
-           chan->chan_id != dma_spec->chan_id)
-               return false;
-
-       dwc->src_id = dma_spec->slave_id;
-       dwc->dst_id = dma_spec->slave_id;
-       dwc->src_master = dwc_get_sms(NULL);
-       dwc->dst_master = dwc_get_dms(NULL);
-
-       return true;
+       return dw_dma_filter(chan, &slave);
 }
 
 static void dw_dma_acpi_controller_register(struct dw_dma *dw)