From patchwork Tue Nov 17 22:37:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 7643351 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BDFE7BF90C for ; Tue, 17 Nov 2015 22:50:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B8D1120547 for ; Tue, 17 Nov 2015 22:50:12 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id ACF5E2051F for ; Tue, 17 Nov 2015 22:50:11 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zyp2j-00080K-5a; Tue, 17 Nov 2015 22:48:05 +0000 Received: from mail-pa0-x229.google.com ([2607:f8b0:400e:c03::229]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zyou9-0005bx-33 for linux-arm-kernel@lists.infradead.org; Tue, 17 Nov 2015 22:39:23 +0000 Received: by pacej9 with SMTP id ej9so22077625pac.2 for ; Tue, 17 Nov 2015 14:38:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=MJmezBJFwVHmYglKKYgUutcpt+2+uwPSFWYll3NX0IE=; b=KoNYhxch/kv4f/BwGKoAzn95m8cWNml93D1S8yika1Wk2TsWk1aAgsiTj7AGJ+8bqp JUnRUkv6f1xOYLYkBXkBHlyLG2aBlBAzSK3i0cpdA2wZlP4H78s432dz5GX/uPgOSr+I 6hAjdtdo7kQZQ2Nfy4HDFQLYpIIwnWglUbNL10B/ZJ1U7tZ3YBd/yRE8pMSLkTtmTYjb ZuCgX1LI7j5it1krq8ahVN13fftfFhI7HuQb7Hg50yVFThTLWaqMmtQFwZr/iKn3P8q+ 7m5zxb8GL2Jukod7Na6xmXs30bXjdv79+TwFbgVTVVh1J5o3SaFcD9b9AiGZTppK/FBX 4xdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=MJmezBJFwVHmYglKKYgUutcpt+2+uwPSFWYll3NX0IE=; b=UaOvzPiYl7m/cXBLd+M9Tqh494BQz6QuwAp161Ahzz5kzJVaSj5gKMZrb5RBsz27UD 7YlAD6Tb2GdwyjSjdCdZnN2kshtKtQ35B0ygpiunPJMPb7rgp7JuNZPYSQVQ3AKOScy0 jfmVuRWs/wdZ/+fOdm1t3R/dVGc4JvMraEZgDwlSipSlWAzJ3HF3NMovaujomtUW/Rq7 ybVrmRhfUtCTOovp/geW+fQplke1VBcYu0YkrimV6UmONbuNYsVTdbuWPepyeG4L0Qqo JsvrszjzXWbIiTFcVt/SmK4UQrWrquHHJr/mtULiPY0GadTJ3Sv+rghHDGUWe/ED4z0a /BaQ== X-Gm-Message-State: ALoCoQmpP5eFrWwYTH32UQjgCU4LPSlVUEiV9+36GUZqWdGNv6oQe/WQtOP/R+Uoj5/dHtgk8nfg X-Received: by 10.66.251.193 with SMTP id zm1mr68125485pac.154.1447799932760; Tue, 17 Nov 2015 14:38:52 -0800 (PST) Received: from ubuntu.localdomain ([8.42.77.226]) by smtp.gmail.com with ESMTPSA id hy1sm14875199pbb.63.2015.11.17.14.38.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 17 Nov 2015 14:38:52 -0800 (PST) From: Lina Iyer To: ulf.hansson@linaro.org, khilman@linaro.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH RFC 17/27] drivers: cpu-pd: Record CPUs that are part of the domain Date: Tue, 17 Nov 2015 15:37:41 -0700 Message-Id: <1447799871-56374-18-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1447799871-56374-1-git-send-email-lina.iyer@linaro.org> References: <1447799871-56374-1-git-send-email-lina.iyer@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151117_143913_362082_254DBEA8 X-CRM114-Status: GOOD ( 19.61 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: k.kozlowski@samsung.com, lorenzo.pieralisi@arm.com, ahaslam@baylibre.com, linux-arm-msm@vger.kernel.org, sboyd@codeaurora.org, msivasub@codeaurora.org, geert@linux-m68k.org, Lina Iyer , agross@codeaurora.org, mtitinger@baylibre.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In order to power down the heirarchy of the CPU domain, the domain needs information about the CPUs in that domain hierarchy . A domain that has sub-domains containing CPU devices, will need information about all the CPUs in the sub-domains as well. Introduce of_attach_cpu_pm_domain() to allow CPU domains to be attached to its parent domain and the information on CPUs attached directly or indirectly be bubbled up the hierarchy. Signed-off-by: Lina Iyer --- drivers/base/power/cpu-pd.c | 96 ++++++++++++++++++++++++++++++++++++++++++++- include/linux/cpu-pd.h | 3 ++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/cpu-pd.c b/drivers/base/power/cpu-pd.c index 9758b8d..617ce54 100644 --- a/drivers/base/power/cpu-pd.c +++ b/drivers/base/power/cpu-pd.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,27 @@ struct cpu_pm_domain *to_cpu_pd(struct generic_pm_domain *d) return res; } +/** + * get_cpus_in_domain() - Recursively parse CPUs in a domain. + */ +static void get_cpus_in_domain(struct generic_pm_domain *genpd, + struct cpumask *mask) +{ + struct gpd_link *link; + struct cpu_pm_domain *pd = to_cpu_pd(genpd); + struct generic_pm_domain *sd; + + if (!cpumask_empty(pd->cpus) && mask != pd->cpus) { + cpumask_or(mask, pd->cpus, mask); + return; + } + + list_for_each_entry(link, &genpd->master_links, master_node) { + sd = link->slave; + get_cpus_in_domain(sd, mask); + } +} + static int cpu_pd_power_off(struct generic_pm_domain *genpd) { struct cpu_pm_domain *pd = to_cpu_pd(genpd); @@ -81,7 +103,8 @@ static void run_cpu(void *unused) pm_runtime_get_noresume(cpu_dev); } -static int of_pm_domain_attach_cpus(struct device_node *dn) +static int of_pm_domain_attach_cpus(struct device_node *dn, + struct cpu_pm_domain *pd) { int cpuid, ret; @@ -126,6 +149,7 @@ static int of_pm_domain_attach_cpus(struct device_node *dn) } else { pm_runtime_enable(cpu_dev); dev_dbg(cpu_dev, "Attached CPU%d to domain\n", cpuid); + cpumask_set_cpu(cpuid, pd->cpus); } } @@ -171,7 +195,7 @@ int of_register_cpu_pm_domain(struct device_node *dn, pd->genpd->name); /* Attach the CPUs to the CPU PM domain */ - ret = of_pm_domain_attach_cpus(dn); + ret = of_pm_domain_attach_cpus(dn, pd); if (ret) of_genpd_del_provider(dn); @@ -213,6 +237,13 @@ struct generic_pm_domain *of_init_cpu_pm_domain(struct device_node *dn, return ERR_PTR(-ENOMEM); } + if (!zalloc_cpumask_var(&pd->cpus, GFP_KERNEL)) { + kfree(pd->genpd->name); + kfree(pd->genpd); + kfree(pd); + return ERR_PTR(-ENOMEM); + } + if (ops) { pd->plat_ops.power_off = ops->power_off; pd->plat_ops.power_on = ops->power_on; @@ -222,6 +253,7 @@ struct generic_pm_domain *of_init_cpu_pm_domain(struct device_node *dn, if (ret) { kfree(pd->genpd->name); kfree(pd->genpd); + kfree(pd->cpus); kfree(pd); return ERR_PTR(ret); } @@ -229,3 +261,63 @@ struct generic_pm_domain *of_init_cpu_pm_domain(struct device_node *dn, return pd->genpd; } EXPORT_SYMBOL(of_init_cpu_pm_domain); + +/** + * of_attach_cpu_pm_domain() - Attach a CPU PM domain to its parent + * @dn: The device node of the CPU PM domain that needs to be attached + * + * The platform code can use this simplfied function to parse the domain + * provider of this device node and attach the genpd associated with @dn + * to it parents. + * + * Note: Both @dn and its domain provider must be initialized using + * of_init_cpu_pm_domain. + */ +int of_attach_cpu_pm_domain(struct device_node *dn) +{ + struct of_phandle_args args; + struct generic_pm_domain *genpd, *parent; + struct cpu_pm_domain *pd; + int ret; + + args.np = dn; + args.args_count = 0; + + genpd = of_genpd_get_from_provider(&args); + if (IS_ERR(genpd)) + return -EINVAL; + + if (!to_cpu_pd(genpd)) { + pr_warn("%s: domain %s is not a CPU domain\n", + __func__, genpd->name); + return -EINVAL; + } + + ret = of_parse_phandle_with_args(dn, "power-domains", + "#power-domain-cells", 0, &args); + if (ret < 0) + return ret; + + parent = of_genpd_get_from_provider(&args); + if (IS_ERR(parent)) + return -EINVAL; + + pd = to_cpu_pd(parent); + if (!pd) { + pr_warn("%s: domain (%s) parent (%s) is non-CPU domain\n", + __func__, genpd->name, parent->name); + return -EINVAL; + } + + ret = pm_genpd_add_subdomain(genpd, parent); + if (ret) { + pr_err("%s: Unable to add sub-domain (%s) to parent (%s)\n", + __func__, genpd->name, parent->name); + return ret; + } + + get_cpus_in_domain(parent, pd->cpus); + + return 0; +} +EXPORT_SYMBOL(of_attach_cpu_pm_domain); diff --git a/include/linux/cpu-pd.h b/include/linux/cpu-pd.h index a2a217d..489ee2f 100644 --- a/include/linux/cpu-pd.h +++ b/include/linux/cpu-pd.h @@ -11,6 +11,7 @@ #ifndef __CPU_PD_H__ #define __CPU_PD_H__ +#include #include #include #include @@ -25,8 +26,10 @@ struct cpu_pm_domain { struct generic_pm_domain *genpd; struct device_node *dn; struct cpu_pd_ops plat_ops; + cpumask_var_t cpus; }; struct generic_pm_domain *of_init_cpu_pm_domain(struct device_node *dn, const struct cpu_pd_ops *ops); +int of_attach_cpu_pm_domain(struct device_node *dn); #endif /* __CPU_PD_H__ */