From patchwork Tue Nov 13 13:08:26 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Figa X-Patchwork-Id: 1733931 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 506A9DF280 for ; Tue, 13 Nov 2012 13:12:28 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TYGFv-0001yh-2S; Tue, 13 Nov 2012 13:10:19 +0000 Received: from mailout3.samsung.com ([203.254.224.33]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TYGFK-0001g0-6b for linux-arm-kernel@lists.infradead.org; Tue, 13 Nov 2012 13:09:44 +0000 Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MDF0072EGJRRJF0@mailout3.samsung.com> for linux-arm-kernel@lists.infradead.org; Tue, 13 Nov 2012 22:09:39 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-15-50a2469338aa Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 0D.C1.01231.39642A05; Tue, 13 Nov 2012 22:09:39 +0900 (KST) Received: from mcdsrvbld02.digital.local ([106.116.37.23]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MDF007RLGI5YYA0@mmp1.samsung.com> for linux-arm-kernel@lists.infradead.org; Tue, 13 Nov 2012 22:09:39 +0900 (KST) From: Tomasz Figa To: linux-samsung-soc@vger.kernel.org Subject: [PATCH v3 3/4] ARM: EXYNOS: pm_domain: Bind devices to power domains using DT Date: Tue, 13 Nov 2012 14:08:26 +0100 Message-id: <1352812107-8777-4-git-send-email-t.figa@samsung.com> X-Mailer: git-send-email 1.7.10 In-reply-to: <1352812107-8777-1-git-send-email-t.figa@samsung.com> References: <1352812107-8777-1-git-send-email-t.figa@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrIJMWRmVeSWpSXmKPExsVy+t9jAd3JbosCDM5uMrHY9PgaqwOjx+Yl 9QGMUVw2Kak5mWWpRfp2CVwZvevWshZcVqk4+GYNcwPjC9kuRk4OCQETiT2XrjJD2GISF+6t Z+ti5OIQEljEKLFl3UN2kISQwGYmiTkbTEBsNgE1ic8Nj9hAbBEBVYnPbQvYQRqYBZ4zSvQt eMYCkhAWiJCYuriNsYuRg4MFqOhPVzRImFfAUWL3mWesEMvkJZ7e7wObwyngJHH81QJGiF2O Eo1LD7BNYORdwMiwilE0tSC5oDgpPddQrzgxt7g0L10vOT93EyPY48+kdjCubLA4xCjAwajE w3vDZWGAEGtiWXFl7iFGCQ5mJRFeA6lFAUK8KYmVValF+fFFpTmpxYcYpTlYlMR5mz1SAoQE 0hNLUrNTUwtSi2CyTBycUg2MYRkZesW8lj/vTqmr/3roXLLC+qvLeDId+T6nbJtwbc8animN L2YJ+dus5qpndtX7fvjF3JcuNc4eCV/ZloRf5xW4LfWTK0fp34uO3zsOrH3JNvnfThMD+7O/ fk29JCBWe3bBUdXECo9wyf+ecwUa9M/7RpjIcPYxXNgp8b+kyG7G/Ys3C5fYK7EUZyQaajEX FScCAIKmrL30AQAA X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121113_080942_694840_9EFA2519 X-CRM114-Status: GOOD ( 17.89 ) X-Spam-Score: -7.6 (-------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-7.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [203.254.224.33 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: kgene.kim@samsung.com, linux-pm@vger.kernel.org, t.figa@samsung.com, tomasz.figa@gmail.com, rjw@sisk.pl, kyungmin.park@samsung.com, thomas.abraham@linaro.org, linux-arm-kernel@lists.infradead.org, m.szyprowski@samsung.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org This patch adds a way to specify bindings between devices and power domains using device tree. A device can be bound to particular power domain by adding a power-domain property containing a phandle to the domain. The device will be bound to the domain before binding a driver to it and unbound after unbinding a driver from it. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park --- .../bindings/arm/exynos/power_domain.txt | 13 +++- arch/arm/mach-exynos/pm_domains.c | 82 ++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt index 843b546..5216b41 100644 --- a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt +++ b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt @@ -4,14 +4,25 @@ Exynos processors include support for multiple power domains which are used to gate power to one or more peripherals on the processor. Required Properties: -- compatiable: should be one of the following. +- compatible: should be one of the following. * samsung,exynos4210-pd - for exynos4210 type power domain. - reg: physical base address of the controller and length of memory mapped region. +Node of a device using power domains must have a samsung,power-domain property +defined with a phandle to respective power domain. + Example: lcd0: power-domain-lcd0 { compatible = "samsung,exynos4210-pd"; reg = <0x10023C00 0x10>; }; + +Example of the node using power domain: + + node { + /* ... */ + samsung,power-domain = <&lcd0>; + /* ... */ + }; diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index 5b7ce7e..4063016 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -83,14 +85,89 @@ static struct exynos_pm_domain PD = { \ } #ifdef CONFIG_OF +static void exynos_add_device_to_domain(struct exynos_pm_domain *pd, + struct device *dev) +{ + int ret; + + dev_dbg(dev, "adding to power domain %s\n", pd->pd.name); + + while(1) { + ret = pm_genpd_add_device(&pd->pd, dev); + if (ret != -EAGAIN) + break; + cond_resched(); + } + + pm_genpd_dev_need_restore(dev, true); +} + +static void exynos_remove_device_from_domain(struct device *dev) +{ + struct generic_pm_domain *genpd = dev_to_genpd(dev); + int ret; + + dev_dbg(dev, "removing from power domain %s\n", genpd->name); + + while(1) { + ret = pm_genpd_remove_device(genpd, dev); + if (ret != -EAGAIN) + break; + cond_resched(); + } +} + +static void exynos_read_domain_from_dt(struct device *dev) +{ + struct platform_device *pd_pdev; + struct exynos_pm_domain *pd; + struct device_node *node; + + node = of_parse_phandle(dev->of_node, "samsung,power-domain", 0); + if (!node) + return; + pd_pdev = of_find_device_by_node(node); + if (!pd_pdev) + return; + pd = platform_get_drvdata(pd_pdev); + exynos_add_device_to_domain(pd, dev); +} + +static int exynos_pm_notifier_call(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct device *dev = data; + + switch (event) { + case BUS_NOTIFY_BIND_DRIVER: + if (dev->of_node) + exynos_read_domain_from_dt(dev); + + break; + + case BUS_NOTIFY_UNBOUND_DRIVER: + exynos_remove_device_from_domain(dev); + + break; + } + return NOTIFY_DONE; +} + +static struct notifier_block platform_nb = { + .notifier_call = exynos_pm_notifier_call, +}; + static __init int exynos_pm_dt_parse_domains(void) { + struct platform_device *pdev; struct device_node *np; for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { struct exynos_pm_domain *pd; int on; + pdev = of_find_device_by_node(np); + pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) { pr_err("%s: failed to allocate memory for domain\n", @@ -105,10 +182,15 @@ static __init int exynos_pm_dt_parse_domains(void) pd->pd.power_on = exynos_pd_power_on; pd->pd.of_node = np; + platform_set_drvdata(pdev, pd); + on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN; pm_genpd_init(&pd->pd, NULL, !on); } + + bus_register_notifier(&platform_bus_type, &platform_nb); + return 0; } #else