diff options
-rw-r--r-- | drivers/dma/dw/core.c | 20 | ||||
-rw-r--r-- | drivers/dma/dw/internal.h | 24 | ||||
-rw-r--r-- | drivers/dma/dw/platform.c | 63 |
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 | ||
922 | bool 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 | } | ||
940 | EXPORT_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 | /** | 46 | extern 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 | */ | ||
53 | static 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 | */ | ||
65 | static 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 | ||
28 | struct dw_dma_of_filter_args { | ||
29 | struct dw_dma *dw; | ||
30 | unsigned int req; | ||
31 | unsigned int src; | ||
32 | unsigned int dst; | ||
33 | }; | ||
34 | |||
35 | static 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 | |||
52 | static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec, | 28 | static 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 |
81 | static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param) | 59 | static 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 | ||
98 | static void dw_dma_acpi_controller_register(struct dw_dma *dw) | 73 | static void dw_dma_acpi_controller_register(struct dw_dma *dw) |