hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/dma/stm32-dmamux.c
....@@ -1,24 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 *
34 * Copyright (C) STMicroelectronics SA 2017
45 * Author(s): M'boumba Cedric Madianga <cedric.madianga@gmail.com>
56 * Pierre-Yves Mordret <pierre-yves.mordret@st.com>
67 *
7
- * License terms: GPL V2.0.
8
- *
9
- * This program is free software; you can redistribute it and/or modify it
10
- * under the terms of the GNU General Public License version 2 as published by
11
- * the Free Software Foundation.
12
- *
13
- * This program is distributed in the hope that it will be useful, but
14
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16
- * details.
17
- *
188 * DMA Router driver for STM32 DMA MUX
199 *
2010 * Based on TI DMA Crossbar driver
21
- *
2211 */
2312
2413 #include <linux/clk.h>
....@@ -28,6 +17,7 @@
2817 #include <linux/module.h>
2918 #include <linux/of_device.h>
3019 #include <linux/of_dma.h>
20
+#include <linux/pm_runtime.h>
3121 #include <linux/reset.h>
3222 #include <linux/slab.h>
3323 #include <linux/spinlock.h>
....@@ -45,12 +35,14 @@
4535 struct stm32_dmamux_data {
4636 struct dma_router dmarouter;
4737 struct clk *clk;
48
- struct reset_control *rst;
4938 void __iomem *iomem;
5039 u32 dma_requests; /* Number of DMA requests connected to DMAMUX */
5140 u32 dmamux_requests; /* Number of DMA requests routed toward DMAs */
5241 spinlock_t lock; /* Protects register access */
5342 unsigned long *dma_inuse; /* Used DMA channel */
43
+ u32 ccr[STM32_DMAMUX_MAX_DMA_REQUESTS]; /* Used to backup CCR register
44
+ * in suspend
45
+ */
5446 u32 dma_reqs[]; /* Number of DMA Request per DMA masters.
5547 * [0] holds number of DMA Masters.
5648 * To be kept at very end end of this structure
....@@ -79,8 +71,7 @@
7971 stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
8072 clear_bit(mux->chan_id, dmamux->dma_inuse);
8173
82
- if (!IS_ERR(dmamux->clk))
83
- clk_disable(dmamux->clk);
74
+ pm_runtime_put_sync(dev);
8475
8576 spin_unlock_irqrestore(&dmamux->lock, flags);
8677
....@@ -146,13 +137,10 @@
146137
147138 /* Set dma request */
148139 spin_lock_irqsave(&dmamux->lock, flags);
149
- if (!IS_ERR(dmamux->clk)) {
150
- ret = clk_enable(dmamux->clk);
151
- if (ret < 0) {
152
- spin_unlock_irqrestore(&dmamux->lock, flags);
153
- dev_err(&pdev->dev, "clk_prep_enable issue: %d\n", ret);
154
- goto error;
155
- }
140
+ ret = pm_runtime_resume_and_get(&pdev->dev);
141
+ if (ret < 0) {
142
+ spin_unlock_irqrestore(&dmamux->lock, flags);
143
+ goto error;
156144 }
157145 spin_unlock_irqrestore(&dmamux->lock, flags);
158146
....@@ -193,14 +181,14 @@
193181 struct stm32_dmamux_data *stm32_dmamux;
194182 struct resource *res;
195183 void __iomem *iomem;
184
+ struct reset_control *rst;
196185 int i, count, ret;
197186 u32 dma_req;
198187
199188 if (!node)
200189 return -ENODEV;
201190
202
- count = device_property_read_u32_array(&pdev->dev, "dma-masters",
203
- NULL, 0);
191
+ count = device_property_count_u32(&pdev->dev, "dma-masters");
204192 if (count < 0) {
205193 dev_err(&pdev->dev, "Can't get DMA master(s) node\n");
206194 return -ENODEV;
....@@ -254,6 +242,7 @@
254242 dev_warn(&pdev->dev, "DMAMUX defaulting on %u requests\n",
255243 stm32_dmamux->dmamux_requests);
256244 }
245
+ pm_runtime_get_noresume(&pdev->dev);
257246
258247 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
259248 iomem = devm_ioremap_resource(&pdev->dev, res);
....@@ -263,18 +252,25 @@
263252 spin_lock_init(&stm32_dmamux->lock);
264253
265254 stm32_dmamux->clk = devm_clk_get(&pdev->dev, NULL);
266
- if (IS_ERR(stm32_dmamux->clk)) {
267
- ret = PTR_ERR(stm32_dmamux->clk);
268
- if (ret == -EPROBE_DEFER)
269
- dev_info(&pdev->dev, "Missing controller clock\n");
255
+ if (IS_ERR(stm32_dmamux->clk))
256
+ return dev_err_probe(&pdev->dev, PTR_ERR(stm32_dmamux->clk),
257
+ "Missing clock controller\n");
258
+
259
+ ret = clk_prepare_enable(stm32_dmamux->clk);
260
+ if (ret < 0) {
261
+ dev_err(&pdev->dev, "clk_prep_enable error: %d\n", ret);
270262 return ret;
271263 }
272264
273
- stm32_dmamux->rst = devm_reset_control_get(&pdev->dev, NULL);
274
- if (!IS_ERR(stm32_dmamux->rst)) {
275
- reset_control_assert(stm32_dmamux->rst);
265
+ rst = devm_reset_control_get(&pdev->dev, NULL);
266
+ if (IS_ERR(rst)) {
267
+ ret = PTR_ERR(rst);
268
+ if (ret == -EPROBE_DEFER)
269
+ goto err_clk;
270
+ } else {
271
+ reset_control_assert(rst);
276272 udelay(2);
277
- reset_control_deassert(stm32_dmamux->rst);
273
+ reset_control_deassert(rst);
278274 }
279275
280276 stm32_dmamux->iomem = iomem;
....@@ -282,25 +278,110 @@
282278 stm32_dmamux->dmarouter.route_free = stm32_dmamux_free;
283279
284280 platform_set_drvdata(pdev, stm32_dmamux);
281
+ pm_runtime_set_active(&pdev->dev);
282
+ pm_runtime_enable(&pdev->dev);
285283
286
- if (!IS_ERR(stm32_dmamux->clk)) {
287
- ret = clk_prepare_enable(stm32_dmamux->clk);
288
- if (ret < 0) {
289
- dev_err(&pdev->dev, "clk_prep_enable error: %d\n", ret);
290
- return ret;
291
- }
292
- }
284
+ pm_runtime_get_noresume(&pdev->dev);
293285
294286 /* Reset the dmamux */
295287 for (i = 0; i < stm32_dmamux->dma_requests; i++)
296288 stm32_dmamux_write(stm32_dmamux->iomem, STM32_DMAMUX_CCR(i), 0);
297289
298
- if (!IS_ERR(stm32_dmamux->clk))
299
- clk_disable(stm32_dmamux->clk);
290
+ pm_runtime_put(&pdev->dev);
300291
301
- return of_dma_router_register(node, stm32_dmamux_route_allocate,
292
+ ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
302293 &stm32_dmamux->dmarouter);
294
+ if (ret)
295
+ goto pm_disable;
296
+
297
+ return 0;
298
+
299
+pm_disable:
300
+ pm_runtime_disable(&pdev->dev);
301
+err_clk:
302
+ clk_disable_unprepare(stm32_dmamux->clk);
303
+
304
+ return ret;
303305 }
306
+
307
+#ifdef CONFIG_PM
308
+static int stm32_dmamux_runtime_suspend(struct device *dev)
309
+{
310
+ struct platform_device *pdev = to_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
+
318
+static int stm32_dmamux_runtime_resume(struct device *dev)
319
+{
320
+ struct platform_device *pdev = to_platform_device(dev);
321
+ struct stm32_dmamux_data *stm32_dmamux = platform_get_drvdata(pdev);
322
+ int ret;
323
+
324
+ ret = clk_prepare_enable(stm32_dmamux->clk);
325
+ if (ret) {
326
+ dev_err(&pdev->dev, "failed to prepare_enable clock\n");
327
+ return ret;
328
+ }
329
+
330
+ return 0;
331
+}
332
+#endif
333
+
334
+#ifdef CONFIG_PM_SLEEP
335
+static int stm32_dmamux_suspend(struct device *dev)
336
+{
337
+ struct platform_device *pdev = to_platform_device(dev);
338
+ struct stm32_dmamux_data *stm32_dmamux = platform_get_drvdata(pdev);
339
+ int i, ret;
340
+
341
+ ret = pm_runtime_resume_and_get(dev);
342
+ if (ret < 0)
343
+ return ret;
344
+
345
+ for (i = 0; i < stm32_dmamux->dma_requests; i++)
346
+ stm32_dmamux->ccr[i] = stm32_dmamux_read(stm32_dmamux->iomem,
347
+ STM32_DMAMUX_CCR(i));
348
+
349
+ pm_runtime_put_sync(dev);
350
+
351
+ pm_runtime_force_suspend(dev);
352
+
353
+ return 0;
354
+}
355
+
356
+static int stm32_dmamux_resume(struct device *dev)
357
+{
358
+ struct platform_device *pdev = to_platform_device(dev);
359
+ struct stm32_dmamux_data *stm32_dmamux = platform_get_drvdata(pdev);
360
+ int i, ret;
361
+
362
+ ret = pm_runtime_force_resume(dev);
363
+ if (ret < 0)
364
+ return ret;
365
+
366
+ ret = pm_runtime_resume_and_get(dev);
367
+ if (ret < 0)
368
+ return ret;
369
+
370
+ for (i = 0; i < stm32_dmamux->dma_requests; i++)
371
+ stm32_dmamux_write(stm32_dmamux->iomem, STM32_DMAMUX_CCR(i),
372
+ stm32_dmamux->ccr[i]);
373
+
374
+ pm_runtime_put_sync(dev);
375
+
376
+ return 0;
377
+}
378
+#endif
379
+
380
+static const struct dev_pm_ops stm32_dmamux_pm_ops = {
381
+ SET_SYSTEM_SLEEP_PM_OPS(stm32_dmamux_suspend, stm32_dmamux_resume)
382
+ SET_RUNTIME_PM_OPS(stm32_dmamux_runtime_suspend,
383
+ stm32_dmamux_runtime_resume, NULL)
384
+};
304385
305386 static const struct of_device_id stm32_dmamux_match[] = {
306387 { .compatible = "st,stm32h7-dmamux" },
....@@ -312,6 +393,7 @@
312393 .driver = {
313394 .name = "stm32-dmamux",
314395 .of_match_table = stm32_dmamux_match,
396
+ .pm = &stm32_dmamux_pm_ops,
315397 },
316398 };
317399