aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/dw/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/dw/platform.c')
-rw-r--r--drivers/dma/dw/platform.c92
1 files changed, 44 insertions, 48 deletions
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
index c5b339af6be5..a630161473a4 100644
--- a/drivers/dma/dw/platform.c
+++ b/drivers/dma/dw/platform.c
@@ -25,72 +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->request_line = fargs->req;
45 dwc->src_master = fargs->src;
46 dwc->dst_master = fargs->dst;
47
48 return true;
49}
50
51static 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,
52 struct of_dma *ofdma) 29 struct of_dma *ofdma)
53{ 30{
54 struct dw_dma *dw = ofdma->of_dma_data; 31 struct dw_dma *dw = ofdma->of_dma_data;
55 struct dw_dma_of_filter_args fargs = { 32 struct dw_dma_slave slave = {
56 .dw = dw, 33 .dma_dev = dw->dma.dev,
57 }; 34 };
58 dma_cap_mask_t cap; 35 dma_cap_mask_t cap;
59 36
60 if (dma_spec->args_count != 3) 37 if (dma_spec->args_count != 3)
61 return NULL; 38 return NULL;
62 39
63 fargs.req = dma_spec->args[0]; 40 slave.src_id = dma_spec->args[0];
64 fargs.src = dma_spec->args[1]; 41 slave.dst_id = dma_spec->args[0];
65 fargs.dst = dma_spec->args[2]; 42 slave.src_master = dma_spec->args[1];
43 slave.dst_master = dma_spec->args[2];
66 44
67 if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS || 45 if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS ||
68 fargs.src >= dw->nr_masters || 46 slave.dst_id >= DW_DMA_MAX_NR_REQUESTS ||
69 fargs.dst >= dw->nr_masters)) 47 slave.src_master >= dw->nr_masters ||
48 slave.dst_master >= dw->nr_masters))
70 return NULL; 49 return NULL;
71 50
72 dma_cap_zero(cap); 51 dma_cap_zero(cap);
73 dma_cap_set(DMA_SLAVE, cap); 52 dma_cap_set(DMA_SLAVE, cap);
74 53
75 /* TODO: there should be a simpler way to do this */ 54 /* TODO: there should be a simpler way to do this */
76 return dma_request_channel(cap, dw_dma_of_filter, &fargs); 55 return dma_request_channel(cap, dw_dma_filter, &slave);
77} 56}
78 57
79#ifdef CONFIG_ACPI 58#ifdef CONFIG_ACPI
80static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param) 59static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
81{ 60{
82 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
83 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 };
84 69
85 if (chan->device->dev != dma_spec->dev || 70 return dw_dma_filter(chan, &slave);
86 chan->chan_id != dma_spec->chan_id)
87 return false;
88
89 dwc->request_line = dma_spec->slave_id;
90 dwc->src_master = dwc_get_sms(NULL);
91 dwc->dst_master = dwc_get_dms(NULL);
92
93 return true;
94} 71}
95 72
96static void dw_dma_acpi_controller_register(struct dw_dma *dw) 73static void dw_dma_acpi_controller_register(struct dw_dma *dw)
@@ -201,10 +178,17 @@ static int dw_probe(struct platform_device *pdev)
201 178
202 chip->dev = dev; 179 chip->dev = dev;
203 180
204 err = dw_dma_probe(chip, pdata); 181 chip->clk = devm_clk_get(chip->dev, "hclk");
182 if (IS_ERR(chip->clk))
183 return PTR_ERR(chip->clk);
184 err = clk_prepare_enable(chip->clk);
205 if (err) 185 if (err)
206 return err; 186 return err;
207 187
188 err = dw_dma_probe(chip, pdata);
189 if (err)
190 goto err_dw_dma_probe;
191
208 platform_set_drvdata(pdev, chip); 192 platform_set_drvdata(pdev, chip);
209 193
210 if (pdev->dev.of_node) { 194 if (pdev->dev.of_node) {
@@ -219,6 +203,10 @@ static int dw_probe(struct platform_device *pdev)
219 dw_dma_acpi_controller_register(chip->dw); 203 dw_dma_acpi_controller_register(chip->dw);
220 204
221 return 0; 205 return 0;
206
207err_dw_dma_probe:
208 clk_disable_unprepare(chip->clk);
209 return err;
222} 210}
223 211
224static int dw_remove(struct platform_device *pdev) 212static int dw_remove(struct platform_device *pdev)
@@ -228,14 +216,18 @@ static int dw_remove(struct platform_device *pdev)
228 if (pdev->dev.of_node) 216 if (pdev->dev.of_node)
229 of_dma_controller_free(pdev->dev.of_node); 217 of_dma_controller_free(pdev->dev.of_node);
230 218
231 return dw_dma_remove(chip); 219 dw_dma_remove(chip);
220 clk_disable_unprepare(chip->clk);
221
222 return 0;
232} 223}
233 224
234static void dw_shutdown(struct platform_device *pdev) 225static void dw_shutdown(struct platform_device *pdev)
235{ 226{
236 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 227 struct dw_dma_chip *chip = platform_get_drvdata(pdev);
237 228
238 dw_dma_shutdown(chip); 229 dw_dma_disable(chip);
230 clk_disable_unprepare(chip->clk);
239} 231}
240 232
241#ifdef CONFIG_OF 233#ifdef CONFIG_OF
@@ -261,7 +253,10 @@ static int dw_suspend_late(struct device *dev)
261 struct platform_device *pdev = to_platform_device(dev); 253 struct platform_device *pdev = to_platform_device(dev);
262 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 254 struct dw_dma_chip *chip = platform_get_drvdata(pdev);
263 255
264 return dw_dma_suspend(chip); 256 dw_dma_disable(chip);
257 clk_disable_unprepare(chip->clk);
258
259 return 0;
265} 260}
266 261
267static int dw_resume_early(struct device *dev) 262static int dw_resume_early(struct device *dev)
@@ -269,7 +264,8 @@ static int dw_resume_early(struct device *dev)
269 struct platform_device *pdev = to_platform_device(dev); 264 struct platform_device *pdev = to_platform_device(dev);
270 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 265 struct dw_dma_chip *chip = platform_get_drvdata(pdev);
271 266
272 return dw_dma_resume(chip); 267 clk_prepare_enable(chip->clk);
268 return dw_dma_enable(chip);
273} 269}
274 270
275#endif /* CONFIG_PM_SLEEP */ 271#endif /* CONFIG_PM_SLEEP */
@@ -281,7 +277,7 @@ static const struct dev_pm_ops dw_dev_pm_ops = {
281static struct platform_driver dw_driver = { 277static struct platform_driver dw_driver = {
282 .probe = dw_probe, 278 .probe = dw_probe,
283 .remove = dw_remove, 279 .remove = dw_remove,
284 .shutdown = dw_shutdown, 280 .shutdown = dw_shutdown,
285 .driver = { 281 .driver = {
286 .name = "dw_dmac", 282 .name = "dw_dmac",
287 .pm = &dw_dev_pm_ops, 283 .pm = &dw_dev_pm_ops,