aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/stm32-dmamux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/stm32-dmamux.c')
-rw-r--r--drivers/dma/stm32-dmamux.c58
1 files changed, 47 insertions, 11 deletions
diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
index b922db90939a..a67119199c45 100644
--- a/drivers/dma/stm32-dmamux.c
+++ b/drivers/dma/stm32-dmamux.c
@@ -28,6 +28,7 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/of_device.h> 29#include <linux/of_device.h>
30#include <linux/of_dma.h> 30#include <linux/of_dma.h>
31#include <linux/pm_runtime.h>
31#include <linux/reset.h> 32#include <linux/reset.h>
32#include <linux/slab.h> 33#include <linux/slab.h>
33#include <linux/spinlock.h> 34#include <linux/spinlock.h>
@@ -79,8 +80,7 @@ static void stm32_dmamux_free(struct device *dev, void *route_data)
79 stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0); 80 stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
80 clear_bit(mux->chan_id, dmamux->dma_inuse); 81 clear_bit(mux->chan_id, dmamux->dma_inuse);
81 82
82 if (!IS_ERR(dmamux->clk)) 83 pm_runtime_put_sync(dev);
83 clk_disable(dmamux->clk);
84 84
85 spin_unlock_irqrestore(&dmamux->lock, flags); 85 spin_unlock_irqrestore(&dmamux->lock, flags);
86 86
@@ -146,13 +146,10 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
146 146
147 /* Set dma request */ 147 /* Set dma request */
148 spin_lock_irqsave(&dmamux->lock, flags); 148 spin_lock_irqsave(&dmamux->lock, flags);
149 if (!IS_ERR(dmamux->clk)) { 149 ret = pm_runtime_get_sync(&pdev->dev);
150 ret = clk_enable(dmamux->clk); 150 if (ret < 0) {
151 if (ret < 0) { 151 spin_unlock_irqrestore(&dmamux->lock, flags);
152 spin_unlock_irqrestore(&dmamux->lock, flags); 152 goto error;
153 dev_err(&pdev->dev, "clk_prep_enable issue: %d\n", ret);
154 goto error;
155 }
156 } 153 }
157 spin_unlock_irqrestore(&dmamux->lock, flags); 154 spin_unlock_irqrestore(&dmamux->lock, flags);
158 155
@@ -254,6 +251,7 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
254 dev_warn(&pdev->dev, "DMAMUX defaulting on %u requests\n", 251 dev_warn(&pdev->dev, "DMAMUX defaulting on %u requests\n",
255 stm32_dmamux->dmamux_requests); 252 stm32_dmamux->dmamux_requests);
256 } 253 }
254 pm_runtime_get_noresume(&pdev->dev);
257 255
258 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 256 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
259 iomem = devm_ioremap_resource(&pdev->dev, res); 257 iomem = devm_ioremap_resource(&pdev->dev, res);
@@ -282,6 +280,8 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
282 stm32_dmamux->dmarouter.route_free = stm32_dmamux_free; 280 stm32_dmamux->dmarouter.route_free = stm32_dmamux_free;
283 281
284 platform_set_drvdata(pdev, stm32_dmamux); 282 platform_set_drvdata(pdev, stm32_dmamux);
283 pm_runtime_set_active(&pdev->dev);
284 pm_runtime_enable(&pdev->dev);
285 285
286 if (!IS_ERR(stm32_dmamux->clk)) { 286 if (!IS_ERR(stm32_dmamux->clk)) {
287 ret = clk_prepare_enable(stm32_dmamux->clk); 287 ret = clk_prepare_enable(stm32_dmamux->clk);
@@ -291,17 +291,52 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
291 } 291 }
292 } 292 }
293 293
294 pm_runtime_get_noresume(&pdev->dev);
295
294 /* Reset the dmamux */ 296 /* Reset the dmamux */
295 for (i = 0; i < stm32_dmamux->dma_requests; i++) 297 for (i = 0; i < stm32_dmamux->dma_requests; i++)
296 stm32_dmamux_write(stm32_dmamux->iomem, STM32_DMAMUX_CCR(i), 0); 298 stm32_dmamux_write(stm32_dmamux->iomem, STM32_DMAMUX_CCR(i), 0);
297 299
298 if (!IS_ERR(stm32_dmamux->clk)) 300 pm_runtime_put(&pdev->dev);
299 clk_disable(stm32_dmamux->clk);
300 301
301 return of_dma_router_register(node, stm32_dmamux_route_allocate, 302 return of_dma_router_register(node, stm32_dmamux_route_allocate,
302 &stm32_dmamux->dmarouter); 303 &stm32_dmamux->dmarouter);
303} 304}
304 305
306#ifdef CONFIG_PM
307static int stm32_dmamux_runtime_suspend(struct device *dev)
308{
309 struct platform_device *pdev =
310 container_of(dev, struct platform_device, dev);
311 struct stm32_dmamux_data *stm32_dmamux = platform_get_drvdata(pdev);
312
313 clk_disable_unprepare(stm32_dmamux->clk);
314
315 return 0;
316}
317
318static int stm32_dmamux_runtime_resume(struct device *dev)
319{
320 struct platform_device *pdev =
321 container_of(dev, struct platform_device, dev);
322 struct stm32_dmamux_data *stm32_dmamux = platform_get_drvdata(pdev);
323 int ret;
324
325 ret = clk_prepare_enable(stm32_dmamux->clk);
326 if (ret) {
327 dev_err(&pdev->dev, "failed to prepare_enable clock\n");
328 return ret;
329 }
330
331 return 0;
332}
333#endif
334
335static const struct dev_pm_ops stm32_dmamux_pm_ops = {
336 SET_RUNTIME_PM_OPS(stm32_dmamux_runtime_suspend,
337 stm32_dmamux_runtime_resume, NULL)
338};
339
305static const struct of_device_id stm32_dmamux_match[] = { 340static const struct of_device_id stm32_dmamux_match[] = {
306 { .compatible = "st,stm32h7-dmamux" }, 341 { .compatible = "st,stm32h7-dmamux" },
307 {}, 342 {},
@@ -312,6 +347,7 @@ static struct platform_driver stm32_dmamux_driver = {
312 .driver = { 347 .driver = {
313 .name = "stm32-dmamux", 348 .name = "stm32-dmamux",
314 .of_match_table = stm32_dmamux_match, 349 .of_match_table = stm32_dmamux_match,
350 .pm = &stm32_dmamux_pm_ops,
315 }, 351 },
316}; 352};
317 353