diff options
| -rw-r--r-- | drivers/dma/shdma.c | 68 | ||||
| -rw-r--r-- | drivers/dma/shdma.h | 1 |
2 files changed, 69 insertions, 0 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 727f51e903d..00b5f320b0e 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
| @@ -1255,6 +1255,8 @@ rst_err: | |||
| 1255 | spin_unlock_irqrestore(&sh_dmae_lock, flags); | 1255 | spin_unlock_irqrestore(&sh_dmae_lock, flags); |
| 1256 | 1256 | ||
| 1257 | pm_runtime_put(&pdev->dev); | 1257 | pm_runtime_put(&pdev->dev); |
| 1258 | pm_runtime_disable(&pdev->dev); | ||
| 1259 | |||
| 1258 | if (dmars) | 1260 | if (dmars) |
| 1259 | iounmap(shdev->dmars); | 1261 | iounmap(shdev->dmars); |
| 1260 | emapdmars: | 1262 | emapdmars: |
| @@ -1313,12 +1315,78 @@ static void sh_dmae_shutdown(struct platform_device *pdev) | |||
| 1313 | sh_dmae_ctl_stop(shdev); | 1315 | sh_dmae_ctl_stop(shdev); |
| 1314 | } | 1316 | } |
| 1315 | 1317 | ||
| 1318 | static int sh_dmae_runtime_suspend(struct device *dev) | ||
| 1319 | { | ||
| 1320 | return 0; | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | static int sh_dmae_runtime_resume(struct device *dev) | ||
| 1324 | { | ||
| 1325 | struct sh_dmae_device *shdev = dev_get_drvdata(dev); | ||
| 1326 | |||
| 1327 | return sh_dmae_rst(shdev); | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | #ifdef CONFIG_PM | ||
| 1331 | static int sh_dmae_suspend(struct device *dev) | ||
| 1332 | { | ||
| 1333 | struct sh_dmae_device *shdev = dev_get_drvdata(dev); | ||
| 1334 | int i; | ||
| 1335 | |||
| 1336 | for (i = 0; i < shdev->pdata->channel_num; i++) { | ||
| 1337 | struct sh_dmae_chan *sh_chan = shdev->chan[i]; | ||
| 1338 | if (sh_chan->descs_allocated) | ||
| 1339 | sh_chan->pm_error = pm_runtime_put_sync(dev); | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | return 0; | ||
| 1343 | } | ||
| 1344 | |||
| 1345 | static int sh_dmae_resume(struct device *dev) | ||
| 1346 | { | ||
| 1347 | struct sh_dmae_device *shdev = dev_get_drvdata(dev); | ||
| 1348 | int i; | ||
| 1349 | |||
| 1350 | for (i = 0; i < shdev->pdata->channel_num; i++) { | ||
| 1351 | struct sh_dmae_chan *sh_chan = shdev->chan[i]; | ||
| 1352 | struct sh_dmae_slave *param = sh_chan->common.private; | ||
| 1353 | |||
| 1354 | if (!sh_chan->descs_allocated) | ||
| 1355 | continue; | ||
| 1356 | |||
| 1357 | if (!sh_chan->pm_error) | ||
| 1358 | pm_runtime_get_sync(dev); | ||
| 1359 | |||
| 1360 | if (param) { | ||
| 1361 | const struct sh_dmae_slave_config *cfg = param->config; | ||
| 1362 | dmae_set_dmars(sh_chan, cfg->mid_rid); | ||
| 1363 | dmae_set_chcr(sh_chan, cfg->chcr); | ||
| 1364 | } else { | ||
| 1365 | dmae_init(sh_chan); | ||
| 1366 | } | ||
| 1367 | } | ||
| 1368 | |||
| 1369 | return 0; | ||
| 1370 | } | ||
| 1371 | #else | ||
| 1372 | #define sh_dmae_suspend NULL | ||
| 1373 | #define sh_dmae_resume NULL | ||
| 1374 | #endif | ||
| 1375 | |||
| 1376 | const struct dev_pm_ops sh_dmae_pm = { | ||
| 1377 | .suspend = sh_dmae_suspend, | ||
| 1378 | .resume = sh_dmae_resume, | ||
| 1379 | .runtime_suspend = sh_dmae_runtime_suspend, | ||
| 1380 | .runtime_resume = sh_dmae_runtime_resume, | ||
| 1381 | }; | ||
| 1382 | |||
| 1316 | static struct platform_driver sh_dmae_driver = { | 1383 | static struct platform_driver sh_dmae_driver = { |
| 1317 | .remove = __exit_p(sh_dmae_remove), | 1384 | .remove = __exit_p(sh_dmae_remove), |
| 1318 | .shutdown = sh_dmae_shutdown, | 1385 | .shutdown = sh_dmae_shutdown, |
| 1319 | .driver = { | 1386 | .driver = { |
| 1320 | .owner = THIS_MODULE, | 1387 | .owner = THIS_MODULE, |
| 1321 | .name = "sh-dma-engine", | 1388 | .name = "sh-dma-engine", |
| 1389 | .pm = &sh_dmae_pm, | ||
| 1322 | }, | 1390 | }, |
| 1323 | }; | 1391 | }; |
| 1324 | 1392 | ||
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index 52e4fb17380..3f9d3cd0658 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h | |||
| @@ -37,6 +37,7 @@ struct sh_dmae_chan { | |||
| 37 | int id; /* Raw id of this channel */ | 37 | int id; /* Raw id of this channel */ |
| 38 | u32 __iomem *base; | 38 | u32 __iomem *base; |
| 39 | char dev_id[16]; /* unique name per DMAC of channel */ | 39 | char dev_id[16]; /* unique name per DMAC of channel */ |
| 40 | int pm_error; | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | struct sh_dmae_device { | 43 | struct sh_dmae_device { |
