aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)