From b375b8ea4fa667d3c76ff550a6fd5ad4fcde0e8d Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 29 Apr 2011 17:09:25 +0000 Subject: [PATCH] --- yaml --- r: 250379 b: refs/heads/master c: 467017b83b5bc445be5d275cf727b4f7ba3d2b2d h: refs/heads/master i: 250377: c93361d22983684d17f3ba63e4511ef272c5202f 250375: e76b5301bc6f5b81052079f4518e139017a1e859 v: v3 --- [refs] | 2 +- trunk/drivers/dma/shdma.c | 68 +++++++++++++++++++++++++++++++++++++++ trunk/drivers/dma/shdma.h | 1 + 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index bcacefb3211c..1285a68e7a65 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2dc666673b5a39d005579a0ef63ae69b5094e686 +refs/heads/master: 467017b83b5bc445be5d275cf727b4f7ba3d2b2d diff --git a/trunk/drivers/dma/shdma.c b/trunk/drivers/dma/shdma.c index 727f51e903d9..00b5f320b0e8 100644 --- a/trunk/drivers/dma/shdma.c +++ b/trunk/drivers/dma/shdma.c @@ -1255,6 +1255,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev) spin_unlock_irqrestore(&sh_dmae_lock, flags); pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + if (dmars) iounmap(shdev->dmars); emapdmars: @@ -1313,12 +1315,78 @@ static void sh_dmae_shutdown(struct platform_device *pdev) sh_dmae_ctl_stop(shdev); } +static int sh_dmae_runtime_suspend(struct device *dev) +{ + return 0; +} + +static int sh_dmae_runtime_resume(struct device *dev) +{ + struct sh_dmae_device *shdev = dev_get_drvdata(dev); + + return sh_dmae_rst(shdev); +} + +#ifdef CONFIG_PM +static int sh_dmae_suspend(struct device *dev) +{ + struct sh_dmae_device *shdev = dev_get_drvdata(dev); + int i; + + for (i = 0; i < shdev->pdata->channel_num; i++) { + struct sh_dmae_chan *sh_chan = shdev->chan[i]; + if (sh_chan->descs_allocated) + sh_chan->pm_error = pm_runtime_put_sync(dev); + } + + return 0; +} + +static int sh_dmae_resume(struct device *dev) +{ + struct sh_dmae_device *shdev = dev_get_drvdata(dev); + int i; + + for (i = 0; i < shdev->pdata->channel_num; i++) { + struct sh_dmae_chan *sh_chan = shdev->chan[i]; + struct sh_dmae_slave *param = sh_chan->common.private; + + if (!sh_chan->descs_allocated) + continue; + + if (!sh_chan->pm_error) + pm_runtime_get_sync(dev); + + if (param) { + const struct sh_dmae_slave_config *cfg = param->config; + dmae_set_dmars(sh_chan, cfg->mid_rid); + dmae_set_chcr(sh_chan, cfg->chcr); + } else { + dmae_init(sh_chan); + } + } + + return 0; +} +#else +#define sh_dmae_suspend NULL +#define sh_dmae_resume NULL +#endif + +const struct dev_pm_ops sh_dmae_pm = { + .suspend = sh_dmae_suspend, + .resume = sh_dmae_resume, + .runtime_suspend = sh_dmae_runtime_suspend, + .runtime_resume = sh_dmae_runtime_resume, +}; + static struct platform_driver sh_dmae_driver = { .remove = __exit_p(sh_dmae_remove), .shutdown = sh_dmae_shutdown, .driver = { .owner = THIS_MODULE, .name = "sh-dma-engine", + .pm = &sh_dmae_pm, }, }; diff --git a/trunk/drivers/dma/shdma.h b/trunk/drivers/dma/shdma.h index 52e4fb173805..3f9d3cd06584 100644 --- a/trunk/drivers/dma/shdma.h +++ b/trunk/drivers/dma/shdma.h @@ -37,6 +37,7 @@ struct sh_dmae_chan { int id; /* Raw id of this channel */ u32 __iomem *base; char dev_id[16]; /* unique name per DMAC of channel */ + int pm_error; }; struct sh_dmae_device {