From patchwork Wed Jul 27 06:14:27 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chanwoo Choi X-Patchwork-Id: 1010842 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p6R6EIhu006752 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 27 Jul 2011 06:14:45 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QlxNf-00032R-Gy; Wed, 27 Jul 2011 06:14:07 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QlxNe-0001NJ-VQ; Wed, 27 Jul 2011 06:14:06 +0000 Received: from mailout4.samsung.com ([203.254.224.34]) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QlxNZ-0001Mz-JR for linux-arm-kernel@lists.infradead.org; Wed, 27 Jul 2011 06:14:04 +0000 Received: from epcpsbgm1.samsung.com (mailout4.samsung.com [203.254.224.34]) by mailout4.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTP id <0LOZ000F2AN3YXD0@mailout4.samsung.com> for linux-arm-kernel@lists.infradead.org; Wed, 27 Jul 2011 15:13:57 +0900 (KST) X-AuditID: cbfee61a-b7cf0ae000006bc6-55-4e2faca4affd Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (MMPCPMTA) with SMTP id E8.5B.27590.4ACAF2E4; Wed, 27 Jul 2011 15:13:56 +0900 (KST) Received: from TNRNDGASPAPP1.tn.corp.samsungelectronics.net ([165.213.149.150]) by mmp2.samsung.com (iPlanet Messaging Server 5.2 Patch 2 (built Jul 14 2004)) with ESMTPA id <0LOZ00LLPAN88P@mmp2.samsung.com> for linux-arm-kernel@lists.infradead.org; Wed, 27 Jul 2011 15:13:56 +0900 (KST) Received: from [127.0.0.1] ([165.213.219.84]) by TNRNDGASPAPP1.tn.corp.samsungelectronics.net with Microsoft SMTPSVC(6.0.3790.4675); Wed, 27 Jul 2011 15:14:17 +0900 Date: Wed, 27 Jul 2011 15:14:27 +0900 From: Chanwoo Choi Subject: [RFC PATCH] DMA: PL330: Update PL330 DMAC to support runtime PM In-reply-to: <1311744697-10264-2-git-send-email-boojin.kim@samsung.com> To: Boojin Kim Message-id: <4E2FACC3.2010109@samsung.com> MIME-version: 1.0 User-Agent: Thunderbird 2.0.0.24 (Windows/20100228) References: <1311744697-10264-1-git-send-email-boojin.kim@samsung.com> <1311744697-10264-2-git-send-email-boojin.kim@samsung.com> X-OriginalArrivalTime: 27 Jul 2011 06:14:17.0224 (UTC) FILETIME=[6A437080:01CC4C24] X-Brightmail-Tracker: AAAAAA== X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110727_021402_150575_7259CFC3 X-CRM114-Status: GOOD ( 24.54 ) X-Spam-Score: -3.5 (---) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-3.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.2 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [203.254.224.34 listed in list.dnswl.org] Cc: Kukjin Kim , Russell King , Vinod Koul , Jassi Brar , Grant Likely , Kyungmin Park , linux-samsung-soc@vger.kernel.org, Mark Brown , Dan Williams , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Wed, 27 Jul 2011 06:14:46 +0000 (UTC) This patch update runtime PM for PL330 DMAC to reduce power consumption. Signed-off-by: Chanwoo Choi Signed-off-by: Kyungmin Park --- The following patch support runtime PM for PL330 DMAC, but the clock of PL330 is always on. If the clock of PL330 is always on, additional power (10mA) is consumed. "[PATCH 01/15] DMA: PL330: Add support runtime PM for PL330 DMAC" http://permalink.gmane.org/gmane.linux.kernel.samsung-soc/5931 arch/arm/plat-samsung/dma-ops.c | 21 +++++++++++ drivers/dma/pl330.c | 76 +++++++++++++-------------------------- include/linux/amba/pl330.h | 54 +++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 51 deletions(-) diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index 9053433..b726e4a 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -33,12 +34,23 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch, struct dma_chan *chan; dma_cap_mask_t mask; struct dma_slave_config slave_config; +#ifdef CONFIG_PM_RUNTIME + struct dma_pl330_chan *pch; + struct dma_pl330_dmac *pdmac; +#endif dma_cap_zero(mask); dma_cap_set(info->cap, mask); chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch); +#ifdef CONFIG_PM_RUNTIME + pch = container_of(chan, struct dma_pl330_chan, chan); + pdmac = pch->dmac; + + pm_runtime_get_sync(pdmac->pif.dev); +#endif + if (info->direction == DMA_FROM_DEVICE) { memset(&slave_config, 0, sizeof(struct dma_slave_config)); slave_config.direction = info->direction; @@ -59,8 +71,17 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch, static int samsung_dmadev_release(unsigned ch, struct s3c2410_dma_client *client) { +#ifdef CONFIG_PM_RUNTIME + struct dma_pl330_chan *pch = + container_of((struct dma_chan *)ch, struct dma_pl330_chan, chan); + struct dma_pl330_dmac *pdmac = pdmac = pch->dmac;; +#endif + dma_release_channel((struct dma_chan *)ch); +#ifdef CONFIG_PM_RUNTIME + pm_runtime_put(pdmac->pif.dev); +#endif return 0; } diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 121c75a..14d0ba6 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -42,57 +42,6 @@ enum desc_status { DONE, }; -struct dma_pl330_chan { - /* Schedule desc completion */ - struct tasklet_struct task; - - /* DMA-Engine Channel */ - struct dma_chan chan; - - /* Last completed cookie */ - dma_cookie_t completed; - - /* List of to be xfered descriptors */ - struct list_head work_list; - - /* Pointer to the DMAC that manages this channel, - * NULL if the channel is available to be acquired. - * As the parent, this DMAC also provides descriptors - * to the channel. - */ - struct dma_pl330_dmac *dmac; - - /* To protect channel manipulation */ - spinlock_t lock; - - /* Token of a hardware channel thread of PL330 DMAC - * NULL if the channel is available to be acquired. - */ - void *pl330_chid; - - /* taks for cyclic capability */ - struct tasklet_struct *cyclic_task; - - bool cyclic; -}; - -struct dma_pl330_dmac { - struct pl330_info pif; - - /* DMA-Engine Device */ - struct dma_device ddma; - - /* Pool of descriptors available for the DMAC's channels */ - struct list_head desc_pool; - /* To protect desc_pool manipulation */ - spinlock_t pool_lock; - - /* Peripheral channels connected to this DMAC */ - struct dma_pl330_chan peripherals[0]; /* keep at end */ - - struct clk *clk; -}; - struct dma_pl330_desc { /* To attach to a queue as child */ struct list_head node; @@ -935,6 +884,18 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan, pi->pcfg.num_peri, pi->pcfg.num_events); +#ifdef CONFIG_PM_RUNTIME + /* disable the power domain */ + ret = pm_runtime_put(&adev->dev); + if (ret < 0) { + dev_err(&adev->dev, "failed to put runtime pm\n"); + ret = -ENODEV; + goto probe_err4; + } +#else + /* disable dma clk */ + clk_disable(pdmac->clk); +#endif return 0; probe_err4: @@ -943,6 +904,13 @@ probe_err3: free_irq(irq, pi); probe_err2: iounmap(pi->base); + +#ifdef CONFIG_PM_RUNTIME + pm_runtime_disable(&adev->dev); + pm_runtime_put(&adev->dev); +#else + clk_disable(pdmac->clk); +#endif probe_err1: release_mem_region(res->start, resource_size(res)); kfree(pdmac); @@ -961,6 +929,12 @@ static int __devexit pl330_remove(struct amba_device *adev) if (!pdmac) return 0; +#ifdef CONFIG_PM_RUNTIME + pm_runtime_get_sync(&adev->dev); +#else + clk_enable(pdmac->clk); +#endif + amba_set_drvdata(adev, NULL); /* Idle the DMAC */ diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h index 17b0ada..d9a63fd 100644 --- a/include/linux/amba/pl330.h +++ b/include/linux/amba/pl330.h @@ -12,6 +12,9 @@ #ifndef __AMBA_PL330_H_ #define __AMBA_PL330_H_ +#include +#include + #include struct dma_pl330_peri { @@ -42,4 +45,55 @@ struct dma_pl330_platdata { unsigned mcbuf_sz; }; +struct dma_pl330_chan { + /* Schedule desc completion */ + struct tasklet_struct task; + + /* DMA-Engine Channel */ + struct dma_chan chan; + + /* Last completed cookie */ + dma_cookie_t completed; + + /* List of to be xfered descriptors */ + struct list_head work_list; + + /* Pointer to the DMAC that manages this channel, + * NULL if the channel is available to be acquired. + * As the parent, this DMAC also provides descriptors + * to the channel. + */ + struct dma_pl330_dmac *dmac; + + /* To protect channel manipulation */ + spinlock_t lock; + + /* Token of a hardware channel thread of PL330 DMAC + * NULL if the channel is available to be acquired. + */ + void *pl330_chid; + + /* taks for cyclic capability */ + struct tasklet_struct *cyclic_task; + + bool cyclic; +}; + +struct dma_pl330_dmac { + struct pl330_info pif; + + /* DMA-Engine Device */ + struct dma_device ddma; + + /* Pool of descriptors available for the DMAC's channels */ + struct list_head desc_pool; + /* To protect desc_pool manipulation */ + spinlock_t pool_lock; + + /* Peripheral channels connected to this DMAC */ + struct dma_pl330_chan peripherals[0]; /* keep at end */ + + struct clk *clk; +}; + #endif /* __AMBA_PL330_H_ */