All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v4 0/8] genpd multiple states v4
@ 2015-04-22  9:45 ahaslam
  2015-04-22  9:45 ` [RFC v4 1/8] PM / Domains: structure changes for multiple states ahaslam
                   ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: ahaslam @ 2015-04-22  9:45 UTC (permalink / raw)
  To: ulf.hansson, khilman, k.kozlowski.k, rjw; +Cc: bcousson, linux-pm, Axel Haslam

From: Axel Haslam <ahaslam@baylibre.com>

Some architectures may have intermediate power
levels between on and off. each state in between
may have its own set of procedures to put the
power domain into that state.

This patch adds the ability to declare multiple
states for a given generic power domain, the idea
is that the deepest state will be entered which
does not violate any of the device or sub-domain
latency constraints.

Changes since v3:
* remove old power on/off function at the end of the
series so that compilation will not break in between.

Changes since v2:
* remove state argument and macros from save/restore
callbacks.

* added init_state for platforms to pass the
initial state when the genpd is initially off.

* convert current genpd users for the structure changes.

* compile tested for shmobile_defconfig, exynos_defconfig,
s3c6400_defconfig u8500_defconfig.

Changes since v1:
* split the changes so that the actual logic that
selects the target state is a separate patch.

* move the cached logic out of the state function and add
it back to default_power_down_ok.

* use static arrays instead of dynamic for state declaration
since its not expected to have lots of intermediate states.
That way we don't have to mess with allocations.

* rename default_power_down_ok_state to power_down_ok_for_state


Axel Haslam (8):
  PM / Domains: structure changes for multiple states
  PM / Domains: select deepest state
  ARM: s3c64xx: pm: Convert to multiple states
  ARM: exynos: pm: Convert to multiple states
  ARM: r8a7779: pm: Convert to multiple states
  ARM: rmobile: pm: Convert to multiple states
  ARM: ux500: pm: Convert to multiple states
  PM / Domains: remove old power on/off callbacks.

 arch/arm/mach-exynos/pm_domains.c    |  6 ++-
 arch/arm/mach-s3c64xx/pm.c           | 57 ++++++++++++++++++--------
 arch/arm/mach-shmobile/pm-r8a7779.c  |  6 ++-
 arch/arm/mach-shmobile/pm-rmobile.c  |  6 ++-
 arch/arm/mach-ux500/pm_domains.c     |  8 +++-
 drivers/base/power/domain.c          | 43 ++++++++++++++------
 drivers/base/power/domain_governor.c | 77 ++++++++++++++++++++++++------------
 include/linux/pm_domain.h            | 21 ++++++++--
 8 files changed, 160 insertions(+), 64 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFC v4 1/8] PM / Domains: structure changes for multiple states
  2015-04-22  9:45 [RFC v4 0/8] genpd multiple states v4 ahaslam
@ 2015-04-22  9:45 ` ahaslam
  2015-04-22 11:17   ` Geert Uytterhoeven
  2015-04-22  9:45 ` [RFC v4 2/8] PM / Domains: select deepest state ahaslam
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 14+ messages in thread
From: ahaslam @ 2015-04-22  9:45 UTC (permalink / raw)
  To: ulf.hansson, khilman, k.kozlowski.k, rjw; +Cc: bcousson, linux-pm, Axel Haslam

From: Axel Haslam <ahaslam@baylibre.com>

Add the structure changes to be able to declare
multiple states. When trying to set a power domain
to off, genpd will be able to choose from an array
of states declared by the platform.

The power on and off callbacks and latencies are
now tied to a particular state.

States should be declared in ascending order from
shallowest to deepest, deepest meaning the state
which takes longer to enter and exit.

if the genpd is initially off, the user should set the
.init_state field when registering the genpd,
so that genpd knows which callbacks to call to set the
domain to on.

An genpd with multiple states would look something like:

struct generic_pm_domain pd1 = {
	.name = "PD1",
	.states = {
		[0] = {
			.name= "D0",
			.power_off = D0_power_off_cb,
			.power_on = D0_power_on_cb,
			.power_off_latency_ns = D0_POWER_OFF_LATENCY,
			.power_on_latency_ns = D0_POWER_ON_LATENCY,
		},
		[1] = {
			.name= "D1",
			.power_off = D1_power_off_cb,
			.power_on = D1_power_on_cb,
			.power_off_latency_ns = D1_POWER_OFF_LATENCY,
			.power_on_latency_ns = D1_POWER_ON_LATENCY,
		},
		[2] = {
			.name= "D2",
			.power_off = D2_power_off_cb,
			.power_on = D2_power_on_cb,
			.power_off_latency_ns = D2_POWER_OFF_LATENCY,
			.power_on_latency_ns = D2_POWER_ON_LATENCY,
		},
	},
	.state_count = 3,
	.init_state = 2,
	[...]
};

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 drivers/base/power/domain.c          | 43 +++++++++++++++++++++++++++---------
 drivers/base/power/domain_governor.c |  8 ++++---
 include/linux/pm_domain.h            | 17 ++++++++++++++
 3 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 45937f8..f60a175 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -141,12 +141,13 @@ static void genpd_set_active(struct generic_pm_domain *genpd)
 
 static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
 {
+	int target_state = genpd->target_state;
 	s64 usecs64;
 
 	if (!genpd->cpuidle_data)
 		return;
 
-	usecs64 = genpd->power_on_latency_ns;
+	usecs64 = genpd->states[target_state].power_on_latency_ns;
 	do_div(usecs64, NSEC_PER_USEC);
 	usecs64 += genpd->cpuidle_data->saved_exit_latency;
 	genpd->cpuidle_data->idle_state->exit_latency = usecs64;
@@ -154,23 +155,24 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
 
 static int genpd_power_on(struct generic_pm_domain *genpd)
 {
+	int target_state = genpd->target_state;
 	ktime_t time_start;
 	s64 elapsed_ns;
 	int ret;
 
-	if (!genpd->power_on)
+	if (!genpd->states[target_state].power_on)
 		return 0;
 
 	time_start = ktime_get();
-	ret = genpd->power_on(genpd);
+	ret = genpd->states[target_state].power_on(genpd);
 	if (ret)
 		return ret;
 
 	elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
-	if (elapsed_ns <= genpd->power_on_latency_ns)
+	if (elapsed_ns <= genpd->states[target_state].power_on_latency_ns)
 		return ret;
 
-	genpd->power_on_latency_ns = elapsed_ns;
+	genpd->states[target_state].power_on_latency_ns = elapsed_ns;
 	genpd->max_off_time_changed = true;
 	genpd_recalc_cpu_exit_latency(genpd);
 	pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
@@ -181,23 +183,24 @@ static int genpd_power_on(struct generic_pm_domain *genpd)
 
 static int genpd_power_off(struct generic_pm_domain *genpd)
 {
+	int target_state = genpd->target_state;
 	ktime_t time_start;
 	s64 elapsed_ns;
 	int ret;
 
-	if (!genpd->power_off)
+	if (!genpd->states[target_state].power_off)
 		return 0;
 
 	time_start = ktime_get();
-	ret = genpd->power_off(genpd);
+	ret = genpd->states[target_state].power_off(genpd);
 	if (ret == -EBUSY)
 		return ret;
 
 	elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
-	if (elapsed_ns <= genpd->power_off_latency_ns)
+	if (elapsed_ns <= genpd->states[target_state].power_off_latency_ns)
 		return ret;
 
-	genpd->power_off_latency_ns = elapsed_ns;
+	genpd->states[target_state].power_off_latency_ns = elapsed_ns;
 	genpd->max_off_time_changed = true;
 	pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
 		genpd->name, "off", elapsed_ns);
@@ -486,6 +489,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
 	struct pm_domain_data *pdd;
 	struct gpd_link *link;
 	unsigned int not_suspended;
+	int target_state;
 	int ret = 0;
 
  start:
@@ -538,6 +542,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
 
 	genpd->status = GPD_STATE_BUSY;
 	genpd->poweroff_task = current;
+	target_state = genpd->target_state;
 
 	list_for_each_entry_reverse(pdd, &genpd->dev_list, list_node) {
 		ret = atomic_read(&genpd->sd_count) == 0 ?
@@ -572,7 +577,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
 		goto out;
 	}
 
-	if (genpd->power_off) {
+	if (genpd->states[target_state].power_off) {
 		if (atomic_read(&genpd->sd_count) > 0) {
 			ret = -EBUSY;
 			goto out;
@@ -1877,6 +1882,17 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
 	genpd->resume_count = 0;
 	genpd->device_count = 0;
 	genpd->max_off_time_ns = -1;
+
+	/*
+	 * set the target off state to the initial off state
+	 * so if the domain is initially off, when the genpd powers on,
+	 * it knows what callback to use.
+	 */
+	genpd->target_state = genpd->init_state;
+	if (genpd->state_count < 1) {
+		pr_err("Initializing genpd %s with invalid state_count %d!\n",
+			genpd->name, genpd->state_count);
+	}
 	genpd->max_off_time_changed = true;
 	genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
 	genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
@@ -2251,6 +2267,7 @@ static int pm_genpd_summary_one(struct seq_file *s,
 		[GPD_STATE_REPEAT] = "off-in-progress",
 		[GPD_STATE_POWER_OFF] = "off"
 	};
+	int target_state = genpd->target_state;
 	struct pm_domain_data *pm_data;
 	const char *kobj_path;
 	struct gpd_link *link;
@@ -2262,7 +2279,11 @@ static int pm_genpd_summary_one(struct seq_file *s,
 
 	if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup)))
 		goto exit;
-	seq_printf(s, "%-30s  %-15s  ", genpd->name, status_lookup[genpd->status]);
+
+	seq_printf(s, "%-30s  %-15s  ", genpd->name,
+		(genpd->status == GPD_STATE_POWER_OFF) ?
+			genpd->states[target_state].name :
+			status_lookup[genpd->status]);
 
 	/*
 	 * Modifications on the list require holding locks on both
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c
index 2a4154a..8630fce 100644
--- a/drivers/base/power/domain_governor.c
+++ b/drivers/base/power/domain_governor.c
@@ -104,6 +104,7 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
 	struct pm_domain_data *pdd;
 	s64 min_off_time_ns;
 	s64 off_on_time_ns;
+	int state = 0;
 
 	if (genpd->max_off_time_changed) {
 		struct gpd_link *link;
@@ -124,8 +125,8 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
 		return genpd->cached_power_down_ok;
 	}
 
-	off_on_time_ns = genpd->power_off_latency_ns +
-				genpd->power_on_latency_ns;
+	off_on_time_ns = genpd->states[state].power_off_latency_ns +
+			genpd->states[state].power_on_latency_ns;
 	/*
 	 * It doesn't make sense to remove power from the domain if saving
 	 * the state of all devices in it and the power off/power on operations
@@ -216,7 +217,8 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
 	 * time and the time needed to turn the domain on is the maximum
 	 * theoretical time this domain can spend in the "off" state.
 	 */
-	genpd->max_off_time_ns = min_off_time_ns - genpd->power_on_latency_ns;
+	genpd->max_off_time_ns = min_off_time_ns -
+			genpd->states[state].power_on_latency_ns;
 	return true;
 }
 
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 080e778..f20c2c0 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -17,6 +17,8 @@
 #include <linux/notifier.h>
 #include <linux/cpuidle.h>
 
+#define GENPD_MAX_NSTATES 10
+
 /* Defines used for the flags field in the struct generic_pm_domain */
 #define GENPD_FLAG_PM_CLK	(1U << 0) /* PM domain uses PM clk */
 
@@ -46,6 +48,16 @@ struct gpd_cpuidle_data {
 	struct cpuidle_state *idle_state;
 };
 
+struct generic_pm_domain;
+
+struct genpd_power_state {
+	char *name;
+	s64 power_off_latency_ns;
+	s64 power_on_latency_ns;
+	int (*power_off)(struct generic_pm_domain *domain);
+	int (*power_on)(struct generic_pm_domain *domain);
+};
+
 struct generic_pm_domain {
 	struct dev_pm_domain domain;	/* PM domain operations */
 	struct list_head gpd_list_node;	/* Node in the global PM domains list */
@@ -80,6 +92,11 @@ struct generic_pm_domain {
 	void (*detach_dev)(struct generic_pm_domain *domain,
 			   struct device *dev);
 	unsigned int flags;		/* Bit field of configs for genpd */
+
+	struct genpd_power_state states[GENPD_MAX_NSTATES];
+	int target_state; /* state that genpd will go to when off */
+	int init_state; /* initial genpd state */
+	int state_count; /* number of states */
 };
 
 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC v4 2/8] PM / Domains: select deepest state
  2015-04-22  9:45 [RFC v4 0/8] genpd multiple states v4 ahaslam
  2015-04-22  9:45 ` [RFC v4 1/8] PM / Domains: structure changes for multiple states ahaslam
@ 2015-04-22  9:45 ` ahaslam
  2015-04-22  9:45 ` [RFC v4 3/8] ARM: s3c64xx: pm: Convert to multiple states ahaslam
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: ahaslam @ 2015-04-22  9:45 UTC (permalink / raw)
  To: ulf.hansson, khilman, k.kozlowski.k, rjw; +Cc: bcousson, linux-pm, Axel Haslam

From: Axel Haslam <ahaslam@baylibre.com>

now that the structures of genpd can support
multiple state definitions, add the logic in
the governor to select the deepest possible
state when powering down.

For this, create the new function power_down_ok_for_state
which will test if a particular state will not violate
the devices and sub-domains constraints.

default_power_down_ok is modified to try each
state starting from the deepest until a valid
state is found or there are no more states to test.

the resulting target state will be valid until
there are latency or constraint changes,
thus, we can avoid looping every power_down,
and use the cached results instead.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 drivers/base/power/domain_governor.c | 71 ++++++++++++++++++++++++------------
 1 file changed, 48 insertions(+), 23 deletions(-)

diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c
index 8630fce..e346a27 100644
--- a/drivers/base/power/domain_governor.c
+++ b/drivers/base/power/domain_governor.c
@@ -97,33 +97,13 @@ static bool default_stop_ok(struct device *dev)
  *
  * This routine must be executed under the PM domain's lock.
  */
-static bool default_power_down_ok(struct dev_pm_domain *pd)
+static bool power_down_ok_for_state(struct dev_pm_domain *pd, int state)
 {
 	struct generic_pm_domain *genpd = pd_to_genpd(pd);
 	struct gpd_link *link;
 	struct pm_domain_data *pdd;
 	s64 min_off_time_ns;
 	s64 off_on_time_ns;
-	int state = 0;
-
-	if (genpd->max_off_time_changed) {
-		struct gpd_link *link;
-
-		/*
-		 * We have to invalidate the cached results for the masters, so
-		 * use the observation that default_power_down_ok() is not
-		 * going to be called for any master until this instance
-		 * returns.
-		 */
-		list_for_each_entry(link, &genpd->slave_links, slave_node)
-			link->master->max_off_time_changed = true;
-
-		genpd->max_off_time_changed = false;
-		genpd->cached_power_down_ok = false;
-		genpd->max_off_time_ns = -1;
-	} else {
-		return genpd->cached_power_down_ok;
-	}
 
 	off_on_time_ns = genpd->states[state].power_off_latency_ns +
 			genpd->states[state].power_on_latency_ns;
@@ -202,8 +182,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
 			min_off_time_ns = constraint_ns;
 	}
 
-	genpd->cached_power_down_ok = true;
-
 	/*
 	 * If the computed minimum device off time is negative, there are no
 	 * latency constraints, so the domain can spend arbitrary time in the
@@ -222,6 +200,53 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
 	return true;
 }
 
+/*
+ * Loop into all the possible low power states
+ * and find the deepest state that does not violate any
+ * constraints. If device constraints did not change,
+ * we can return the cached value and use the target_state
+ * calculated previously.
+ */
+static bool default_power_down_ok(struct dev_pm_domain *pd)
+{
+	struct generic_pm_domain *genpd = pd_to_genpd(pd);
+	int last_state_idx = genpd->state_count - 1;
+	struct gpd_link *link;
+	bool retval = false;
+	int i;
+
+	/*
+	 * if there was no change on max_off_time, we can return the
+	 * cached value and we dont need to find a new target_state
+	 */
+	if (!genpd->max_off_time_changed)
+		return genpd->cached_power_down_ok;
+
+	/*
+	 * We have to invalidate the cached results for the masters, so
+	 * use the observation that default_power_down_ok() is not
+	 * going to be called for any master until this instance
+	 * returns.
+	 */
+	list_for_each_entry(link, &genpd->slave_links, slave_node)
+		link->master->max_off_time_changed = true;
+
+	genpd->max_off_time_ns = -1;
+	genpd->max_off_time_changed = false;
+
+	/* find a state to power down to, starting from the deepest */
+	for (i = 0; i < genpd->state_count; i++) {
+		if (power_down_ok_for_state(pd, last_state_idx - i)) {
+			genpd->target_state = last_state_idx - i;
+			retval = true;
+			break;
+		}
+	}
+
+	genpd->cached_power_down_ok = retval;
+	return retval;
+}
+
 static bool always_on_power_down_ok(struct dev_pm_domain *domain)
 {
 	return false;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC v4 3/8] ARM: s3c64xx: pm: Convert to multiple states
  2015-04-22  9:45 [RFC v4 0/8] genpd multiple states v4 ahaslam
  2015-04-22  9:45 ` [RFC v4 1/8] PM / Domains: structure changes for multiple states ahaslam
  2015-04-22  9:45 ` [RFC v4 2/8] PM / Domains: select deepest state ahaslam
@ 2015-04-22  9:45 ` ahaslam
  2015-04-22  9:45 ` [RFC v4 4/8] ARM: exynos: " ahaslam
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: ahaslam @ 2015-04-22  9:45 UTC (permalink / raw)
  To: ulf.hansson, khilman, k.kozlowski.k, rjw; +Cc: bcousson, linux-pm, Axel Haslam

From: Axel Haslam <ahaslam@baylibre.com>

The generic power domain framework added structure changes
to support multiple intermediate states when powering off a domain.

These changes are needed to prevent compilation breaks with
the new structures.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 arch/arm/mach-s3c64xx/pm.c | 57 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 41 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index aaf7bea..8536d14 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -89,8 +89,12 @@ static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
 	.name = "IROM",
 	.ena = S3C64XX_NORMALCFG_IROM_ON,
 	.pd = {
-		.power_off = s3c64xx_pd_off,
-		.power_on = s3c64xx_pd_on,
+		.states[0] = {
+			.name = "off",
+			.power_off = s3c64xx_pd_off,
+			.power_on = s3c64xx_pd_on,
+		},
+		.state_count = 1,
 	},
 };
 
@@ -99,8 +103,11 @@ static struct s3c64xx_pm_domain s3c64xx_pm_etm = {
 	.ena = S3C64XX_NORMALCFG_DOMAIN_ETM_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_ETM,
 	.pd = {
-		.power_off = s3c64xx_pd_off,
-		.power_on = s3c64xx_pd_on,
+		.states[0] = {
+			.name = "off",
+			.power_off = s3c64xx_pd_off,
+			.power_on = s3c64xx_pd_on,
+		}
 	},
 };
 
@@ -109,8 +116,11 @@ static struct s3c64xx_pm_domain s3c64xx_pm_s = {
 	.ena = S3C64XX_NORMALCFG_DOMAIN_S_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_S,
 	.pd = {
-		.power_off = s3c64xx_pd_off,
-		.power_on = s3c64xx_pd_on,
+		.states[0] = {
+			.name = "off",
+			.power_off = s3c64xx_pd_off,
+			.power_on = s3c64xx_pd_on,
+		}
 	},
 };
 
@@ -119,8 +129,11 @@ static struct s3c64xx_pm_domain s3c64xx_pm_f = {
 	.ena = S3C64XX_NORMALCFG_DOMAIN_F_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_F,
 	.pd = {
-		.power_off = s3c64xx_pd_off,
-		.power_on = s3c64xx_pd_on,
+		.states[0] = {
+			.name = "off",
+			.power_off = s3c64xx_pd_off,
+			.power_on = s3c64xx_pd_on,
+		}
 	},
 };
 
@@ -129,8 +142,11 @@ static struct s3c64xx_pm_domain s3c64xx_pm_p = {
 	.ena = S3C64XX_NORMALCFG_DOMAIN_P_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_P,
 	.pd = {
-		.power_off = s3c64xx_pd_off,
-		.power_on = s3c64xx_pd_on,
+		.states[0] = {
+			.name = "off",
+			.power_off = s3c64xx_pd_off,
+			.power_on = s3c64xx_pd_on,
+		}
 	},
 };
 
@@ -139,8 +155,11 @@ static struct s3c64xx_pm_domain s3c64xx_pm_i = {
 	.ena = S3C64XX_NORMALCFG_DOMAIN_I_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_I,
 	.pd = {
-		.power_off = s3c64xx_pd_off,
-		.power_on = s3c64xx_pd_on,
+		.states[0] = {
+			.name = "off",
+			.power_off = s3c64xx_pd_off,
+			.power_on = s3c64xx_pd_on,
+		}
 	},
 };
 
@@ -148,8 +167,11 @@ static struct s3c64xx_pm_domain s3c64xx_pm_g = {
 	.name = "G",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
 	.pd = {
-		.power_off = s3c64xx_pd_off,
-		.power_on = s3c64xx_pd_on,
+		.states[0] = {
+			.name = "off",
+			.power_off = s3c64xx_pd_off,
+			.power_on = s3c64xx_pd_on,
+		}
 	},
 };
 
@@ -158,8 +180,11 @@ static struct s3c64xx_pm_domain s3c64xx_pm_v = {
 	.ena = S3C64XX_NORMALCFG_DOMAIN_V_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_V,
 	.pd = {
-		.power_off = s3c64xx_pd_off,
-		.power_on = s3c64xx_pd_on,
+		.states[0] = {
+			.name = "off",
+			.power_off = s3c64xx_pd_off,
+			.power_on = s3c64xx_pd_on,
+		}
 	},
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC v4 4/8] ARM: exynos: pm: Convert to multiple states
  2015-04-22  9:45 [RFC v4 0/8] genpd multiple states v4 ahaslam
                   ` (2 preceding siblings ...)
  2015-04-22  9:45 ` [RFC v4 3/8] ARM: s3c64xx: pm: Convert to multiple states ahaslam
@ 2015-04-22  9:45 ` ahaslam
  2015-04-22  9:45 ` [RFC v4 5/8] ARM: r8a7779: " ahaslam
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: ahaslam @ 2015-04-22  9:45 UTC (permalink / raw)
  To: ulf.hansson, khilman, k.kozlowski.k, rjw; +Cc: bcousson, linux-pm, Axel Haslam

From: Axel Haslam <ahaslam@baylibre.com>

The generic power domain framework added structure changes
to support multiple intermediate states when powering off a domain.

These changes are needed to prevent compilation breaks with
the new structures.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 arch/arm/mach-exynos/pm_domains.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index 37266a8..01fc620 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -128,8 +128,10 @@ static __init int exynos4_pm_init_power_domain(void)
 		pd->pd.name = kstrdup(np->name, GFP_KERNEL);
 		pd->name = pd->pd.name;
 		pd->base = of_iomap(np, 0);
-		pd->pd.power_off = exynos_pd_power_off;
-		pd->pd.power_on = exynos_pd_power_on;
+		pd->pd.states[0].power_off = exynos_pd_power_off;
+		pd->pd.states[0].power_on = exynos_pd_power_on;
+		pd->pd.states[0].name = "off";
+		pd->pd.state_count = 1;
 
 		pd->oscclk = clk_get(dev, "oscclk");
 		if (IS_ERR(pd->oscclk))
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC v4 5/8] ARM: r8a7779: pm: Convert to multiple states
  2015-04-22  9:45 [RFC v4 0/8] genpd multiple states v4 ahaslam
                   ` (3 preceding siblings ...)
  2015-04-22  9:45 ` [RFC v4 4/8] ARM: exynos: " ahaslam
@ 2015-04-22  9:45 ` ahaslam
  2015-04-22  9:45 ` [RFC v4 6/8] ARM: rmobile: " ahaslam
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: ahaslam @ 2015-04-22  9:45 UTC (permalink / raw)
  To: ulf.hansson, khilman, k.kozlowski.k, rjw; +Cc: bcousson, linux-pm, Axel Haslam

From: Axel Haslam <ahaslam@baylibre.com>

The generic power domain framework added structure changes
to support multiple intermediate states when powering off a domain.

These changes are needed to prevent compilation breaks with
the new structures.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 arch/arm/mach-shmobile/pm-r8a7779.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c
index 44a74c4..2f1d1e8 100644
--- a/arch/arm/mach-shmobile/pm-r8a7779.c
+++ b/arch/arm/mach-shmobile/pm-r8a7779.c
@@ -86,8 +86,10 @@ static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
 	genpd->flags = GENPD_FLAG_PM_CLK;
 	pm_genpd_init(genpd, NULL, false);
 	genpd->dev_ops.active_wakeup = pd_active_wakeup;
-	genpd->power_off = pd_power_down;
-	genpd->power_on = pd_power_up;
+	genpd->states[0].power_off = pd_power_down;
+	genpd->states[0].power_on = pd_power_up;
+	genpd->states[0].name = "off";
+	genpd->state_count = 1;
 
 	if (pd_is_off(&r8a7779_pd->genpd))
 		pd_power_up(&r8a7779_pd->genpd);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC v4 6/8] ARM: rmobile: pm: Convert to multiple states
  2015-04-22  9:45 [RFC v4 0/8] genpd multiple states v4 ahaslam
                   ` (4 preceding siblings ...)
  2015-04-22  9:45 ` [RFC v4 5/8] ARM: r8a7779: " ahaslam
@ 2015-04-22  9:45 ` ahaslam
  2015-04-22  9:45 ` [RFC v4 7/8] ARM: ux500: " ahaslam
  2015-04-22  9:45 ` [RFC v4 8/8] PM / Domains: remove old power on/off callbacks ahaslam
  7 siblings, 0 replies; 14+ messages in thread
From: ahaslam @ 2015-04-22  9:45 UTC (permalink / raw)
  To: ulf.hansson, khilman, k.kozlowski.k, rjw; +Cc: bcousson, linux-pm, Axel Haslam

From: Axel Haslam <ahaslam@baylibre.com>

The generic power domain framework added structure changes
to support multiple intermediate states when powering off a domain.

These changes are needed to prevent compilation breaks with
the new structures.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 arch/arm/mach-shmobile/pm-rmobile.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
index 9501820..8badaae 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.c
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -156,8 +156,10 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
 	genpd->flags = GENPD_FLAG_PM_CLK;
 	pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
 	genpd->dev_ops.active_wakeup	= rmobile_pd_active_wakeup;
-	genpd->power_off		= rmobile_pd_power_down;
-	genpd->power_on			= rmobile_pd_power_up;
+	genpd->states[0].power_off	= rmobile_pd_power_down;
+	genpd->states[0].power_on	= rmobile_pd_power_up;
+	genpd->states[0].name		= "off";
+	genpd->state_count		= 1;
 	genpd->attach_dev		= rmobile_pd_attach_dev;
 	genpd->detach_dev		= rmobile_pd_detach_dev;
 	__rmobile_pd_power_up(rmobile_pd, false);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC v4 7/8] ARM: ux500: pm: Convert to multiple states
  2015-04-22  9:45 [RFC v4 0/8] genpd multiple states v4 ahaslam
                   ` (5 preceding siblings ...)
  2015-04-22  9:45 ` [RFC v4 6/8] ARM: rmobile: " ahaslam
@ 2015-04-22  9:45 ` ahaslam
  2015-04-22  9:45 ` [RFC v4 8/8] PM / Domains: remove old power on/off callbacks ahaslam
  7 siblings, 0 replies; 14+ messages in thread
From: ahaslam @ 2015-04-22  9:45 UTC (permalink / raw)
  To: ulf.hansson, khilman, k.kozlowski.k, rjw; +Cc: bcousson, linux-pm, Axel Haslam

From: Axel Haslam <ahaslam@baylibre.com>

The generic power domain framework added structure changes
to support multiple intermediate states when powering off a domain.

These changes are needed to prevent compilation breaks with
the new structures.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 arch/arm/mach-ux500/pm_domains.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-ux500/pm_domains.c b/arch/arm/mach-ux500/pm_domains.c
index 4d71c90..7b685e3 100644
--- a/arch/arm/mach-ux500/pm_domains.c
+++ b/arch/arm/mach-ux500/pm_domains.c
@@ -41,8 +41,12 @@ static int pd_power_on(struct generic_pm_domain *domain)
 
 static struct generic_pm_domain ux500_pm_domain_vape = {
 	.name = "VAPE",
-	.power_off = pd_power_off,
-	.power_on = pd_power_on,
+	.states[0] = {
+		.power_off = pd_power_off,
+		.power_on = pd_power_on,
+		.name = "off",
+	},
+	.state_count = 1,
 };
 
 static struct generic_pm_domain *ux500_pm_domains[NR_DOMAINS] = {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC v4 8/8] PM / Domains: remove old power on/off callbacks.
  2015-04-22  9:45 [RFC v4 0/8] genpd multiple states v4 ahaslam
                   ` (6 preceding siblings ...)
  2015-04-22  9:45 ` [RFC v4 7/8] ARM: ux500: " ahaslam
@ 2015-04-22  9:45 ` ahaslam
  7 siblings, 0 replies; 14+ messages in thread
From: ahaslam @ 2015-04-22  9:45 UTC (permalink / raw)
  To: ulf.hansson, khilman, k.kozlowski.k, rjw; +Cc: bcousson, linux-pm, Axel Haslam

From: Axel Haslam <ahaslam@baylibre.com>

Now that all known users have been converted to use the state
version of the callbacks, we can remove the default callbacks
without breaking compilation.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
 include/linux/pm_domain.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index f20c2c0..9bf9217 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -78,10 +78,6 @@ struct generic_pm_domain {
 	unsigned int suspended_count;	/* System suspend device counter */
 	unsigned int prepared_count;	/* Suspend counter of prepared devices */
 	bool suspend_power_off;	/* Power status before system suspend */
-	int (*power_off)(struct generic_pm_domain *domain);
-	s64 power_off_latency_ns;
-	int (*power_on)(struct generic_pm_domain *domain);
-	s64 power_on_latency_ns;
 	struct gpd_dev_ops dev_ops;
 	s64 max_off_time_ns;	/* Maximum allowed "suspended" time. */
 	bool max_off_time_changed;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [RFC v4 1/8] PM / Domains: structure changes for multiple states
  2015-04-22  9:45 ` [RFC v4 1/8] PM / Domains: structure changes for multiple states ahaslam
@ 2015-04-22 11:17   ` Geert Uytterhoeven
  2015-04-22 13:23     ` Axel Haslam
  0 siblings, 1 reply; 14+ messages in thread
From: Geert Uytterhoeven @ 2015-04-22 11:17 UTC (permalink / raw)
  To: ahaslam
  Cc: Ulf Hansson, Kevin Hilman, Krzysztof Kozłowski,
	Rafael J. Wysocki, Benoit Cousson, Linux PM list

On Wed, Apr 22, 2015 at 11:45 AM,  <ahaslam@baylibre.com> wrote:
> From: Axel Haslam <ahaslam@baylibre.com>
>
> Add the structure changes to be able to declare
> multiple states. When trying to set a power domain
> to off, genpd will be able to choose from an array
> of states declared by the platform.
>
> The power on and off callbacks and latencies are
> now tied to a particular state.
>
> States should be declared in ascending order from
> shallowest to deepest, deepest meaning the state
> which takes longer to enter and exit.
>
> if the genpd is initially off, the user should set the
> .init_state field when registering the genpd,
> so that genpd knows which callbacks to call to set the
> domain to on.

The initial state may depend on various factors (hardware default,
boot loader, previously loaded kernel, ...). This is even true with the
current binary states.

> index 45937f8..f60a175 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c

> @@ -154,23 +155,24 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
>
>  static int genpd_power_on(struct generic_pm_domain *genpd)
>  {
> +       int target_state = genpd->target_state;
>         ktime_t time_start;
>         s64 elapsed_ns;
>         int ret;
>
> -       if (!genpd->power_on)
> +       if (!genpd->states[target_state].power_on)
>                 return 0;
>

While your series now looks compilable for all patch steps, it's not
bisectable: the right hook won't be called until the platform is
converted to support multiple states.

I think you can fix this by e.g. using -1 for the target_state on non-converted
platforms, and doing:

        if (target_state < 0) {
                if (!genpd->power_on)
                        return 0;
        } else {
                if (!genpd->states[target_state].power_on)
                        return 0;
        }

and

        ret = target_state < 0 ? genpd->power_on(genpd)
                               : genpd->states[target_state].power_on(genpd);

The checks for a negative target_state can be removed only after
all platforms have been converted.

> --- a/include/linux/pm_domain.h
> +++ b/include/linux/pm_domain.h
> @@ -17,6 +17,8 @@
>  #include <linux/notifier.h>
>  #include <linux/cpuidle.h>
>
> +#define GENPD_MAX_NSTATES 10
> +
>  /* Defines used for the flags field in the struct generic_pm_domain */
>  #define GENPD_FLAG_PM_CLK      (1U << 0) /* PM domain uses PM clk */
>
> @@ -46,6 +48,16 @@ struct gpd_cpuidle_data {
>         struct cpuidle_state *idle_state;
>  };
>
> +struct generic_pm_domain;
> +
> +struct genpd_power_state {
> +       char *name;
> +       s64 power_off_latency_ns;
> +       s64 power_on_latency_ns;
> +       int (*power_off)(struct generic_pm_domain *domain);
> +       int (*power_on)(struct generic_pm_domain *domain);
> +};
> +
>  struct generic_pm_domain {
>         struct dev_pm_domain domain;    /* PM domain operations */
>         struct list_head gpd_list_node; /* Node in the global PM domains list */
> @@ -80,6 +92,11 @@ struct generic_pm_domain {
>         void (*detach_dev)(struct generic_pm_domain *domain,
>                            struct device *dev);
>         unsigned int flags;             /* Bit field of configs for genpd */
> +
> +       struct genpd_power_state states[GENPD_MAX_NSTATES];

I think states should be a pointer to an array, not an array of 10 entries, to
avoid wasting memory on systems with a small number of states.

E.g. on r8a73a4, we have 24 PM Domains.
That would waste 24 * 9 * 32 = 6912 bytes of memory.

What about keeping the .power_o{ff,n}() callbacks in struct generic_pm_domain,
but adding a state index parameter to the callbacks?
That would save even more memory on systems where all callbacks are identical.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC v4 1/8] PM / Domains: structure changes for multiple states
  2015-04-22 11:17   ` Geert Uytterhoeven
@ 2015-04-22 13:23     ` Axel Haslam
  2015-04-22 13:57       ` Geert Uytterhoeven
  2015-04-22 14:50       ` Axel Haslam
  0 siblings, 2 replies; 14+ messages in thread
From: Axel Haslam @ 2015-04-22 13:23 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Ulf Hansson, Kevin Hilman, Krzysztof Kozłowski,
	Rafael J. Wysocki, Benoit Cousson, Linux PM list

Hi Geert,

>>
>> if the genpd is initially off, the user should set the
>> .init_state field when registering the genpd,
>> so that genpd knows which callbacks to call to set the
>> domain to on.
>
> The initial state may depend on various factors (hardware default,
> boot loader, previously loaded kernel, ...). This is even true with the
> current binary states.
>

This would mean that the inital state of the genpd cannot be
hardcoded right?

maybe there should be the option to add  platform callback
to get the initial state from platform specific code or default
to the hardcoded one? this callback could do whatever it needs to return 
the on/off status and if off, the index of the current state.


>> index 45937f8..f60a175 100644
>> --- a/drivers/base/power/domain.c
>> +++ b/drivers/base/power/domain.c
>
>> @@ -154,23 +155,24 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
>>
>>   static int genpd_power_on(struct generic_pm_domain *genpd)
>>   {
>> +       int target_state = genpd->target_state;
>>          ktime_t time_start;
>>          s64 elapsed_ns;
>>          int ret;
>>
>> -       if (!genpd->power_on)
>> +       if (!genpd->states[target_state].power_on)
>>                  return 0;
>>
>
> While your series now looks compilable for all patch steps, it's not
> bisectable: the right hook won't be called until the platform is
> converted to support multiple states.
>
> I think you can fix this by e.g. using -1 for the target_state on non-converted
> platforms, and doing:
>
>          if (target_state < 0) {
>                  if (!genpd->power_on)
>                          return 0;
>          } else {
>                  if (!genpd->states[target_state].power_on)
>                          return 0;
>          }
>
> and
>
>          ret = target_state < 0 ? genpd->power_on(genpd)
>                                 : genpd->states[target_state].power_on(genpd);
>
> The checks for a negative target_state can be removed only after
> all platforms have been converted.
>

Ok, on the next series i will make sure the old callbacks are used until 
they are converted.

>> +       struct genpd_power_state states[GENPD_MAX_NSTATES];
>
> I think states should be a pointer to an array, not an array of 10 entries, to
> avoid wasting memory on systems with a small number of states.

Ok, I had it as pointer on array on the first series, i changed it
to make the code simpler, but i can go back to pointer to array
to save memory.

>
> E.g. on r8a73a4, we have 24 PM Domains.
> That would waste 24 * 9 * 32 = 6912 bytes of memory.
>
> What about keeping the .power_o{ff,n}() callbacks in struct generic_pm_domain,
> but adding a state index parameter to the callbacks?
> That would save even more memory on systems where all callbacks are identical.

makes sense.

Thanks,
Axel

>
> Gr{oetje,eeting}s,
>
>                          Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                  -- Linus Torvalds
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC v4 1/8] PM / Domains: structure changes for multiple states
  2015-04-22 13:23     ` Axel Haslam
@ 2015-04-22 13:57       ` Geert Uytterhoeven
  2015-04-22 16:26         ` Axel Haslam
  2015-04-22 14:50       ` Axel Haslam
  1 sibling, 1 reply; 14+ messages in thread
From: Geert Uytterhoeven @ 2015-04-22 13:57 UTC (permalink / raw)
  To: Axel Haslam
  Cc: Ulf Hansson, Kevin Hilman, Krzysztof Kozłowski,
	Rafael J. Wysocki, Benoit Cousson, Linux PM list

Hi Axel,

On Wed, Apr 22, 2015 at 3:23 PM, Axel Haslam <ahaslam@baylibre.com> wrote:
>>> if the genpd is initially off, the user should set the
>>> .init_state field when registering the genpd,
>>> so that genpd knows which callbacks to call to set the
>>> domain to on.
>>
>> The initial state may depend on various factors (hardware default,
>> boot loader, previously loaded kernel, ...). This is even true with the
>> current binary states.
>
> This would mean that the inital state of the genpd cannot be
> hardcoded right?

Indeed. And it should be filled in by the platform code before registration.

>> What about keeping the .power_o{ff,n}() callbacks in struct
>> generic_pm_domain,
>> but adding a state index parameter to the callbacks?
>> That would save even more memory on systems where all callbacks are
>> identical.
>
> makes sense.

It will complicate compilability/bisectability, though.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC v4 1/8] PM / Domains: structure changes for multiple states
  2015-04-22 13:23     ` Axel Haslam
  2015-04-22 13:57       ` Geert Uytterhoeven
@ 2015-04-22 14:50       ` Axel Haslam
  1 sibling, 0 replies; 14+ messages in thread
From: Axel Haslam @ 2015-04-22 14:50 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Ulf Hansson, Kevin Hilman, Krzysztof Kozłowski,
	Rafael J. Wysocki, Benoit Cousson, Linux PM list

Hi Geert,

>>
>> While your series now looks compilable for all patch steps, it's not
>> bisectable: the right hook won't be called until the platform is
>> converted to support multiple states.
>>
>> I think you can fix this by e.g. using -1 for the target_state on
>> non-converted
>> platforms, and doing:
>>
>>          if (target_state < 0) {
>>                  if (!genpd->power_on)
>>                          return 0;
>>          } else {
>>                  if (!genpd->states[target_state].power_on)
>>                          return 0;
>>          }
>>
>> and
>>
>>          ret = target_state < 0 ? genpd->power_on(genpd)
>>                                 :
>> genpd->states[target_state].power_on(genpd);
>>
>> The checks for a negative target_state can be removed only after
>> all platforms have been converted.
>>

instead of adding checks for negative target state,
i think we can use a single state as a placeholder for the
old callbacks.

would this be an acceptable solution?

on init i can add something like:

+       if (genpd->power_off || genpd->power_on) {
+               pr_warn("Using old genpd callbacks\n");
+               genpd->state_count = 1;
+               genpd->states[0].name = "OFF";
+               genpd->states[0].power_off = genpd->power_off;
+               genpd->states[0].power_off_latency_ns =
+                       genpd->power_off_latency_ns;
+               genpd->states[0].power_on = genpd->power_on;
+               genpd->states[0].power_on_latency_ns =
+                               genpd->power_on_latency_ns;
+       }
+

this way, old callbacks are called in case the platform
has not been converted yet.

Regards
Axel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC v4 1/8] PM / Domains: structure changes for multiple states
  2015-04-22 13:57       ` Geert Uytterhoeven
@ 2015-04-22 16:26         ` Axel Haslam
  0 siblings, 0 replies; 14+ messages in thread
From: Axel Haslam @ 2015-04-22 16:26 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Ulf Hansson, Kevin Hilman, Krzysztof Kozłowski,
	Rafael J. Wysocki, Benoit Cousson, Linux PM list

Hi Geert,

On 22/04/2015 15:57, Geert Uytterhoeven wrote:
> Hi Axel,
>
> On Wed, Apr 22, 2015 at 3:23 PM, Axel Haslam <ahaslam@baylibre.com> wrote:
>>>> if the genpd is initially off, the user should set the
>>>> .init_state field when registering the genpd,
>>>> so that genpd knows which callbacks to call to set the
>>>> domain to on.
>>>
>>> The initial state may depend on various factors (hardware default,
>>> boot loader, previously loaded kernel, ...). This is even true with the
>>> current binary states.
>>
>> This would mean that the inital state of the genpd cannot be
>> hardcoded right?
>
> Indeed. And it should be filled in by the platform code before registration.
>
>>> What about keeping the .power_o{ff,n}() callbacks in struct
>>> generic_pm_domain,
>>> but adding a state index parameter to the callbacks?
>>> That would save even more memory on systems where all callbacks are
>>> identical.
>>
>> makes sense.
>
> It will complicate compilability/bisectability, though.
>

since the genpd pointer is allready an argument to the .power_o{ff,n}() 
callbacks, it would be simpler if the platform could check 
genpd->target_state to know what state is powering on/off to, instead of 
adding a new argument.

That way i can remove the power on/off callbacks from the state array,
and there are no big issues with bisectability.

regards,
Axel

> Gr{oetje,eeting}s,
>
>                          Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                  -- Linus Torvalds
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2015-04-22 16:26 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-22  9:45 [RFC v4 0/8] genpd multiple states v4 ahaslam
2015-04-22  9:45 ` [RFC v4 1/8] PM / Domains: structure changes for multiple states ahaslam
2015-04-22 11:17   ` Geert Uytterhoeven
2015-04-22 13:23     ` Axel Haslam
2015-04-22 13:57       ` Geert Uytterhoeven
2015-04-22 16:26         ` Axel Haslam
2015-04-22 14:50       ` Axel Haslam
2015-04-22  9:45 ` [RFC v4 2/8] PM / Domains: select deepest state ahaslam
2015-04-22  9:45 ` [RFC v4 3/8] ARM: s3c64xx: pm: Convert to multiple states ahaslam
2015-04-22  9:45 ` [RFC v4 4/8] ARM: exynos: " ahaslam
2015-04-22  9:45 ` [RFC v4 5/8] ARM: r8a7779: " ahaslam
2015-04-22  9:45 ` [RFC v4 6/8] ARM: rmobile: " ahaslam
2015-04-22  9:45 ` [RFC v4 7/8] ARM: ux500: " ahaslam
2015-04-22  9:45 ` [RFC v4 8/8] PM / Domains: remove old power on/off callbacks ahaslam

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.