From patchwork Fri Apr 29 17:09:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 741611 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3THA7MZ030047 for ; Fri, 29 Apr 2011 17:10:09 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760263Ab1D2RJv (ORCPT ); Fri, 29 Apr 2011 13:09:51 -0400 Received: from moutng.kundenserver.de ([212.227.126.171]:50438 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755873Ab1D2RJ1 (ORCPT ); Fri, 29 Apr 2011 13:09:27 -0400 Received: from axis700.grange (pD9EB9180.dip0.t-ipconnect.de [217.235.145.128]) by mrelayeu.kundenserver.de (node=mreu0) with ESMTP (Nemesis) id 0MLC4r-1QG8JD0t4j-000FGH; Fri, 29 Apr 2011 19:09:26 +0200 Received: by axis700.grange (Postfix, from userid 1000) id DCEA0189B89; Fri, 29 Apr 2011 19:09:25 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by axis700.grange (Postfix) with ESMTP id D9E94189B88; Fri, 29 Apr 2011 19:09:25 +0200 (CEST) Date: Fri, 29 Apr 2011 19:09:25 +0200 (CEST) From: Guennadi Liakhovetski X-X-Sender: lyakh@axis700.grange To: linux-sh@vger.kernel.org cc: linux-kernel@vger.kernel.org, Dan Williams , Simon Horman , Magnus Damm Subject: [PATCH 2/2] dmaengine: shdma: add runtime- and system-level power management In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Provags-ID: V02:K0:MwnemiBIMyL7P398YioUSJDmA0/BwaQTZePna1uTami Ppw44g7wv3c9KdHUR+EEwZdrXtOh+Pt2RtUISFBbX7unDmiYl/ 2HAc8EZSeLuavfCiPKLCoT6mI49+148GGutoTF+BRirzJP8uhh Fb1ekqKdttXso6KuyAFb3Cnvd/CFB8KrVNqMfDWj5SSTjzsNR3 hs2uiBvoh2hm+mADHcSJUHsMMHOaMogc919BPv8fhY= Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 29 Apr 2011 17:10:09 +0000 (UTC) This patch extends and fixes runtime power management in the shdma driver to support powering down the DMA controller and adds support for system-level suspend and resume. Signed-off-by: Guennadi Liakhovetski --- drivers/dma/shdma.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 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 d0f402b..dcc1b21 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -1254,6 +1254,8 @@ rst_err: spin_unlock_irq(&sh_dmae_lock); 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/drivers/dma/shdma.h b/drivers/dma/shdma.h index 52e4fb1..3f9d3cd 100644 --- a/drivers/dma/shdma.h +++ b/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 {