All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lina Iyer <lina.iyer@linaro.org>
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 <lina.iyer@linaro.org>
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	[thread overview]
Message-ID: <1455310238-8963-7-git-send-email-lina.iyer@linaro.org> (raw)
In-Reply-To: <1455310238-8963-1-git-send-email-lina.iyer@linaro.org>

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 <lina.iyer@linaro.org>
---
 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 <linux/cpu.h>
+#include <linux/cpumask.h>
 #include <linux/cpu_domains.h>
 #include <linux/cpu_pm.h>
 #include <linux/device.h>
@@ -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 <linux/cpumask.h>
+
 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);
 };
 
-- 
2.1.4

WARNING: multiple messages have this Message-ID (diff)
From: lina.iyer@linaro.org (Lina Iyer)
To: linux-arm-kernel@lists.infradead.org
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	[thread overview]
Message-ID: <1455310238-8963-7-git-send-email-lina.iyer@linaro.org> (raw)
In-Reply-To: <1455310238-8963-1-git-send-email-lina.iyer@linaro.org>

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 <lina.iyer@linaro.org>
---
 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 <linux/cpu.h>
+#include <linux/cpumask.h>
 #include <linux/cpu_domains.h>
 #include <linux/cpu_pm.h>
 #include <linux/device.h>
@@ -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 <linux/cpumask.h>
+
 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);
 };
 
-- 
2.1.4

  parent reply	other threads:[~2016-02-12 20:51 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-12 20:50 [RFC v2 00/12] PM: SoC idle support using PM domains Lina Iyer
2016-02-12 20:50 ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 01/12] PM / Domains: Abstract genpd locking Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 18:08   ` Stephen Boyd
2016-02-26 18:08     ` Stephen Boyd
2016-03-01 16:55     ` Lina Iyer
2016-03-01 16:55       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 02/12] PM / Domains: Support IRQ safe PM domains Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 18:17   ` Stephen Boyd
2016-02-26 18:17     ` Stephen Boyd
2016-03-01 17:44     ` Lina Iyer
2016-03-01 17:44       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 03/12] PM / cpu_domains: Setup PM domains for CPUs/clusters Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-17 23:38   ` Lina Iyer
2016-02-17 23:38     ` Lina Iyer
2016-02-18 17:29   ` [BUG FIX] PM / cpu_domains: Check for NULL callbacks Lina Iyer
2016-02-18 17:29     ` Lina Iyer
2016-02-18 17:46     ` Rafael J. Wysocki
2016-02-18 17:46       ` Rafael J. Wysocki
2016-02-18 22:51       ` Lina Iyer
2016-02-18 22:51         ` Lina Iyer
2016-02-26 19:10   ` [RFC v2 03/12] PM / cpu_domains: Setup PM domains for CPUs/clusters Stephen Boyd
2016-02-26 19:10     ` Stephen Boyd
2016-03-01 18:00     ` Lina Iyer
2016-03-01 18:00       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 04/12] ARM: cpuidle: Add runtime PM support for CPUs Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 18:24   ` Stephen Boyd
2016-02-26 18:24     ` Stephen Boyd
2016-03-01 18:36     ` Lina Iyer
2016-03-01 18:36       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 05/12] timer: Export next wake up of a CPU Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-12 20:50 ` Lina Iyer [this message]
2016-02-12 20:50   ` [RFC v2 06/12] PM / cpu_domains: Record CPUs that are part of the domain Lina Iyer
2016-02-26 19:20   ` Stephen Boyd
2016-02-26 19:20     ` Stephen Boyd
2016-03-01 19:24     ` Lina Iyer
2016-03-01 19:24       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 07/12] PM / cpu_domains: Add PM Domain governor for CPUs Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 19:33   ` Stephen Boyd
2016-02-26 19:33     ` Stephen Boyd
2016-03-01 19:32     ` Lina Iyer
2016-03-01 19:32       ` Lina Iyer
2016-03-01 19:35       ` Stephen Boyd
2016-03-01 19:35         ` Stephen Boyd
2016-02-12 20:50 ` [RFC v2 08/12] Documentation / cpu_domains: Describe CPU PM domains setup and governor Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 19:43   ` Stephen Boyd
2016-02-26 19:43     ` Stephen Boyd
2016-03-01 19:36     ` Lina Iyer
2016-03-01 19:36       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 09/12] drivers: firmware: psci: Allow OS Initiated suspend mode Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 10/12] ARM64: psci: Support cluster idle states for OS-Initiated Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 11/12] ARM64: dts: Add PSCI cpuidle support for MSM8916 Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 12/12] ARM64: dts: Define CPU power domain " Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 19:50   ` Stephen Boyd
2016-02-26 19:50     ` Stephen Boyd
2016-03-01 19:41     ` Lina Iyer
2016-03-01 19:41       ` Lina Iyer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1455310238-8963-7-git-send-email-lina.iyer@linaro.org \
    --to=lina.iyer@linaro.org \
    --cc=agross@codeaurora.org \
    --cc=ahaslam@baylibre.com \
    --cc=geert@linux-m68k.org \
    --cc=k.kozlowski@samsung.com \
    --cc=khilman@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=msivasub@codeaurora.org \
    --cc=mtitinger@baylibre.com \
    --cc=rjw@rjwysocki.net \
    --cc=sboyd@codeaurora.org \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.