aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2014-08-19 13:29:16 -0400
committerVinod Koul <vinod.koul@intel.com>2014-09-11 02:18:13 -0400
commit4d130de20c3f39fc1a1aecd3969b50d49ff2e358 (patch)
tree516da38bd5d9114a6a3b2140fb8c69a873162976 /drivers/dma
parent8950052029874a6738552debb45077c596e90e6b (diff)
dmaengine: dw: introduce generic filter function
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>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/dw/core.c20
-rw-r--r--drivers/dma/dw/internal.h24
-rw-r--r--drivers/dma/dw/platform.c63
3 files changed, 40 insertions, 67 deletions
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index 1c4521283fa9..10e43eae61a7 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -919,6 +919,26 @@ err_desc_get:
919 return NULL; 919 return NULL;
920} 920}
921 921
922bool dw_dma_filter(struct dma_chan *chan, void *param)
923{
924 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
925 struct dw_dma_slave *dws = param;
926
927 if (!dws || dws->dma_dev != chan->device->dev)
928 return false;
929
930 /* We have to copy data since dws can be temporary storage */
931
932 dwc->src_id = dws->src_id;
933 dwc->dst_id = dws->dst_id;
934
935 dwc->src_master = dws->src_master;
936 dwc->dst_master = dws->dst_master;
937
938 return true;
939}
940EXPORT_SYMBOL_GPL(dw_dma_filter);
941
922/* 942/*
923 * Fix sconfig's burst size according to dw_dmac. We need to convert them as: 943 * Fix sconfig's burst size according to dw_dmac. We need to convert them as:
924 * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3. 944 * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
diff --git a/drivers/dma/dw/internal.h b/drivers/dma/dw/internal.h
index 43cc1dfad5c9..2c8d02f52737 100644
--- a/drivers/dma/dw/internal.h
+++ b/drivers/dma/dw/internal.h
@@ -43,28 +43,6 @@ int dw_dma_resume(struct dw_dma_chip *chip);
43 43
44#endif /* CONFIG_PM_SLEEP */ 44#endif /* CONFIG_PM_SLEEP */
45 45
46/** 46extern bool dw_dma_filter(struct dma_chan *chan, void *param);
47 * dwc_get_dms - get destination master
48 * @slave: pointer to the custom slave configuration
49 *
50 * Returns destination master in the custom slave configuration if defined, or
51 * default value otherwise.
52 */
53static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
54{
55 return slave ? slave->dst_master : 0;
56}
57
58/**
59 * dwc_get_sms - get source master
60 * @slave: pointer to the custom slave configuration
61 *
62 * Returns source master in the custom slave configuration if defined, or
63 * default value otherwise.
64 */
65static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
66{
67 return slave ? slave->src_master : 1;
68}
69 47
70#endif /* _DW_DMAC_INTERNAL_H */ 48#endif /* _DW_DMAC_INTERNAL_H */
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
index 7aa3cd33fdec..860c9acf3fef 100644
--- a/drivers/dma/dw/platform.c
+++ b/drivers/dma/dw/platform.c
@@ -25,74 +25,49 @@
25 25
26#include "internal.h" 26#include "internal.h"
27 27
28struct dw_dma_of_filter_args {
29 struct dw_dma *dw;
30 unsigned int req;
31 unsigned int src;
32 unsigned int dst;
33};
34
35static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
36{
37 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
38 struct dw_dma_of_filter_args *fargs = param;
39
40 /* Ensure the device matches our channel */
41 if (chan->device != &fargs->dw->dma)
42 return false;
43
44 dwc->src_id = fargs->req;
45 dwc->dst_id = fargs->req;
46 dwc->src_master = fargs->src;
47 dwc->dst_master = fargs->dst;
48
49 return true;
50}
51
52static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec, 28static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
53 struct of_dma *ofdma) 29 struct of_dma *ofdma)
54{ 30{
55 struct dw_dma *dw = ofdma->of_dma_data; 31 struct dw_dma *dw = ofdma->of_dma_data;
56 struct dw_dma_of_filter_args fargs = { 32 struct dw_dma_slave slave = {
57 .dw = dw, 33 .dma_dev = dw->dma.dev,
58 }; 34 };
59 dma_cap_mask_t cap; 35 dma_cap_mask_t cap;
60 36
61 if (dma_spec->args_count != 3) 37 if (dma_spec->args_count != 3)
62 return NULL; 38 return NULL;
63 39
64 fargs.req = dma_spec->args[0]; 40 slave.src_id = dma_spec->args[0];
65 fargs.src = dma_spec->args[1]; 41 slave.dst_id = dma_spec->args[0];
66 fargs.dst = dma_spec->args[2]; 42 slave.src_master = dma_spec->args[1];
43 slave.dst_master = dma_spec->args[2];
67 44
68 if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS || 45 if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS ||
69 fargs.src >= dw->nr_masters || 46 slave.dst_id >= DW_DMA_MAX_NR_REQUESTS ||
70 fargs.dst >= dw->nr_masters)) 47 slave.src_master >= dw->nr_masters ||
48 slave.dst_master >= dw->nr_masters))
71 return NULL; 49 return NULL;
72 50
73 dma_cap_zero(cap); 51 dma_cap_zero(cap);
74 dma_cap_set(DMA_SLAVE, cap); 52 dma_cap_set(DMA_SLAVE, cap);
75 53
76 /* TODO: there should be a simpler way to do this */ 54 /* TODO: there should be a simpler way to do this */
77 return dma_request_channel(cap, dw_dma_of_filter, &fargs); 55 return dma_request_channel(cap, dw_dma_filter, &slave);
78} 56}
79 57
80#ifdef CONFIG_ACPI 58#ifdef CONFIG_ACPI
81static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param) 59static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
82{ 60{
83 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
84 struct acpi_dma_spec *dma_spec = param; 61 struct acpi_dma_spec *dma_spec = param;
62 struct dw_dma_slave slave = {
63 .dma_dev = dma_spec->dev,
64 .src_id = dma_spec->slave_id,
65 .dst_id = dma_spec->slave_id,
66 .src_master = 1,
67 .dst_master = 0,
68 };
85 69
86 if (chan->device->dev != dma_spec->dev || 70 return dw_dma_filter(chan, &slave);
87 chan->chan_id != dma_spec->chan_id)
88 return false;
89
90 dwc->src_id = dma_spec->slave_id;
91 dwc->dst_id = dma_spec->slave_id;
92 dwc->src_master = dwc_get_sms(NULL);
93 dwc->dst_master = dwc_get_dms(NULL);
94
95 return true;
96} 71}
97 72
98static void dw_dma_acpi_controller_register(struct dw_dma *dw) 73static void dw_dma_acpi_controller_register(struct dw_dma *dw)