From patchwork Fri Feb 12 20:50:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 8297331 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 18A539F1C5 for ; Fri, 12 Feb 2016 20:51:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1783F20444 for ; Fri, 12 Feb 2016 20:51:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 37A7C2044B for ; Fri, 12 Feb 2016 20:51:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751105AbcBLUvb (ORCPT ); Fri, 12 Feb 2016 15:51:31 -0500 Received: from mail-pf0-f177.google.com ([209.85.192.177]:34198 "EHLO mail-pf0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751016AbcBLUva (ORCPT ); Fri, 12 Feb 2016 15:51:30 -0500 Received: by mail-pf0-f177.google.com with SMTP id x65so52984435pfb.1 for ; Fri, 12 Feb 2016 12:51:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=S20YEntyVNwW0Se5DIjR0hEuEP3YMolQLoPuvnFC9FY=; b=ChfTYNkttp9jnjh6DWyOT7fZ6+IuNj9sfywdGQnEs2UOHcEaf+4da+KFQwN2NrthzW bWIELg0R0QR7CzvO+FrTEH6DrW4Ybn3mAUczvMM3EGqtqKE50rThZavWEYHG4zs+KW+S ENRcWM+xjkV+l7nYU8y84fY/bJuQtB1gjTwvE= 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=S20YEntyVNwW0Se5DIjR0hEuEP3YMolQLoPuvnFC9FY=; b=ZMl0nQ8grWRV/OPdtqzijVk8krd7xed7lI0mD2YysW2QWW5duEtTxLWnEJDxPntyP5 ydGhSelbEiWN1x1mmu7J35uqnzki5WEJsZZ4Ms043VhAybMFah4vO5sktoVzk+Ggb2Er yHMzIV/wH5iZMVroGQ4kdJLPVrsthUWeAU76r4TFKdPrYUhzCAKTplWVz+kYFgdi1aym UGPE5GBhHo/jPAVCsdRsfFyYZUlsKYM3Uva9GQIPphprV3r4FCRuq3R8pZ05IoWh6id6 D6nwx2nNeJBsFCWjPIyZ4roWxoRHGLEjN7m601BJA4Xwr3HrmrKMkqUlcSKCXMaeoJHb 0+4w== X-Gm-Message-State: AG10YOROd+rcLDe3lHsiDtbD8jnnQdBAshiZVZ/Ol8dbEyUJBNeujFh5xEPgLa3PZcOIwqvl X-Received: by 10.98.18.8 with SMTP id a8mr5117741pfj.41.1455310290361; Fri, 12 Feb 2016 12:51:30 -0800 (PST) Received: from ubuntu.localdomain ([172.56.8.98]) by smtp.gmail.com with ESMTPSA id x12sm21401070pfi.88.2016.02.12.12.51.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 12 Feb 2016 12:51:29 -0800 (PST) From: Lina Iyer To: ulf.hansson@linaro.org, khilman@kernel.org, rjw@rjwysocki.net, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: geert@linux-m68k.org, k.kozlowski@samsung.com, msivasub@codeaurora.org, agross@codeaurora.org, sboyd@codeaurora.org, linux-arm-msm@vger.kernel.org, lorenzo.pieralisi@arm.com, ahaslam@baylibre.com, mtitinger@baylibre.com, Lina Iyer Subject: [RFC v2 06/12] PM / cpu_domains: Record CPUs that are part of the domain Date: Fri, 12 Feb 2016 13:50:32 -0700 Message-Id: <1455310238-8963-7-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1455310238-8963-1-git-send-email-lina.iyer@linaro.org> References: <1455310238-8963-1-git-send-email-lina.iyer@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,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 a CPU domain, the domain needs information about the CPUs in that domain. The reference counting for the CPU devices in a domain is done by genpd. In order to understand the idle time for the domain, it is necessary to know which CPUs are part of the domain, so the domain governor may understand the sleep durations of the comprising CPU devices and make a judicious decision on the domain's idle state. This extends to the parent of such domains, which may have multiple such CPU domains and therefore would need to know the sleep patterns of all the CPUs in all the CPU domains. To aid this functionality, traverse up the parent chain and set the CPU in the cpumasks while attaching a CPU to its domain. This mask is provided in the callback to the platform driver to help identify the CPUs in the domain that is being powered off. Signed-off-by: Lina Iyer --- drivers/base/power/cpu_domains.c | 27 ++++++++++++++++++++++++--- include/linux/cpu_domains.h | 4 +++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/base/power/cpu_domains.c b/drivers/base/power/cpu_domains.c index 981592f..c99710c 100644 --- a/drivers/base/power/cpu_domains.c +++ b/drivers/base/power/cpu_domains.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -27,6 +28,7 @@ struct cpu_pm_domain { struct cpu_pd_ops ops; struct generic_pm_domain *genpd; struct cpu_pm_domain *parent; + cpumask_var_t cpus; }; /* List of CPU PM domains we care about */ @@ -50,7 +52,7 @@ struct cpu_pm_domain *to_cpu_pd(struct generic_pm_domain *d) return res; } -static int cpu_pd_attach_cpu(int cpu) +static int cpu_pd_attach_cpu(struct cpu_pm_domain *cpu_pd, int cpu) { int ret; struct device *cpu_dev; @@ -70,6 +72,11 @@ static int cpu_pd_attach_cpu(int cpu) else dev_dbg(cpu_dev, "Attached to domain\n"); + while (!ret && cpu_pd) { + cpumask_set_cpu(cpu, cpu_pd->cpus); + cpu_pd = cpu_pd->parent; + }; + return ret; } @@ -85,7 +92,8 @@ static int cpu_pd_power_off(struct generic_pm_domain *genpd) struct cpu_pm_domain *pd = to_cpu_pd(genpd); return pd->ops.power_off(genpd->state_idx, - genpd->states[genpd->state_idx].param); + genpd->states[genpd->state_idx].param, + pd->cpus); } /** @@ -118,6 +126,9 @@ static struct generic_pm_domain *of_init_cpu_pm_domain(struct device_node *dn, if (!pd) goto fail; + if (!zalloc_cpumask_var(&pd->cpus, GFP_KERNEL)) + goto fail; + pd->genpd = genpd; pd->genpd->power_off = cpu_pd_power_off; pd->genpd->power_on = cpu_pd_power_on; @@ -148,6 +159,8 @@ fail: kfree(genpd); kfree(genpd->name); + if (pd) + kfree(pd->cpus); kfree(pd); return ERR_PTR(ret); } @@ -224,6 +237,7 @@ int of_setup_cpu_pd_single(int cpu, const struct cpu_pd_ops *ops) struct device_node *dn; struct generic_pm_domain *genpd; + struct cpu_pm_domain *cpu_pd; dn = of_get_cpu_node(cpu, NULL); if (!dn) @@ -239,7 +253,14 @@ int of_setup_cpu_pd_single(int cpu, const struct cpu_pd_ops *ops) if (IS_ERR(genpd)) return PTR_ERR(genpd); - return cpu_pd_attach_cpu(cpu); + cpu_pd = to_cpu_pd(genpd); + if (!cpu_pd) { + pr_err("%s: Genpd was created outside CPU PM domains\n", + __func__); + return -ENOENT; + } + + return cpu_pd_attach_cpu(cpu_pd, cpu); } EXPORT_SYMBOL(of_setup_cpu_pd_single); diff --git a/include/linux/cpu_domains.h b/include/linux/cpu_domains.h index bab4846..0c539f0 100644 --- a/include/linux/cpu_domains.h +++ b/include/linux/cpu_domains.h @@ -11,8 +11,10 @@ #ifndef __CPU_DOMAINS_H__ #define __CPU_DOMAINS_H__ +#include + struct cpu_pd_ops { - int (*power_off)(u32 state_idx, u32 param); + int (*power_off)(u32 state_idx, u32 param, const struct cpumask *mask); int (*power_on)(void); };