All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
@ 2012-08-15 10:02 ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Santosh Shilimkar, Nishanth Menon
  Cc: Jean Pihet

Here is a re-spin after some comments and suggestions after review.

Implement the functional states for the power domains:
- unify the API to use the functional states. pwrdm_set_next_fpwrst
  now is the function to control the power domains power and logic
  states,
- reorganize the powerdomain API in internal and external parts,
  in powerdomain.h [1]
- protect the power domain state change by a lock in
  pwrdm_set_next_fpwrst,
- introduce the functional states for power domains power states and
  logic power states, and the conversion functions between the
  functional and internal states,
- program the logic power state of power domains from the functional
  states, in pwrdm_set_next_fpwrst
- convert the OMAP2/3/4 PM code to use the updated API,
- provide the power domains statistics by functional states,
- provide ftrace tracepoints with the functional state,
- provide error logs in critical code, which makes the development
  easier.

Note: [1] the physical split of internal and external APIs into
      different header files is not part of this series, it comes as
      a separate patch set.


Based on mainline kernel 3.6.0-rc1.

Tested on OMAP3 Beagleboard, with suspend and cpuidle in RET and
OFF modes.


History:
 v5:
 - complete rework after review and suggestions,
 - improved locking on next state read/write; spinlock instead of mutex
 - added more error logging in critical code,

 v4:
 - reworked the code after internal review and testing with OMAP3&4 device
   OFF,
 - fixed the tracepoints generation code,
 - introduce a function that returns power domains achievable functional
   states, in order to return a valid state for power domains that only
   support some of the power states. Although it has been tested OK the
   code is in RFC state.

 v3:
 - fix a bug in OMAP3 cpuidle which prevented the IO wake-ups in PER

 v2:
 - add the logic power states,
 - provide the power domains statistics by functional states

 v1:
 - initial implementation, in RFC state


Jean Pihet (7):
  ARM: OMAP2+: PM: introduce power domains functional states
  ARM: OMAP2+: PM: introduce power domains achievable functional states
  ARM: OMAP2+: PM: add a lock to protect the powerdomains next state
  ARM: OMAP2+: PM: use the functional power states API
  ARM: OMAP2+: PM: use power domain functional state in stats counters
  ARM: OMAP2+: PM debug: trace the functional power domains states
  ARM: OMAP2+: PM: reorganize the powerdomain API in public and private
    parts

Nishanth Menon (1):
  ARM: OMAP2+: powerdomain: add error logs

 arch/arm/mach-omap2/cpuidle34xx.c          |   58 ++--
 arch/arm/mach-omap2/cpuidle44xx.c          |   24 +-
 arch/arm/mach-omap2/omap-hotplug.c         |    2 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c  |   39 ++--
 arch/arm/mach-omap2/pm-debug.c             |   15 +-
 arch/arm/mach-omap2/pm24xx.c               |   14 +-
 arch/arm/mach-omap2/pm34xx.c               |   79 +++---
 arch/arm/mach-omap2/pm44xx.c               |   24 +-
 arch/arm/mach-omap2/powerdomain-common.c   |   99 ++++++
 arch/arm/mach-omap2/powerdomain.c          |  456 +++++++++++++++++++++++++---
 arch/arm/mach-omap2/powerdomain.h          |  152 ++++++---
 arch/arm/mach-omap2/powerdomain2xxx_3xxx.c |    6 +
 arch/arm/mach-omap2/powerdomain44xx.c      |    3 +
 13 files changed, 753 insertions(+), 218 deletions(-)

-- 
1.7.7.6


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

* [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
@ 2012-08-15 10:02 ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

Here is a re-spin after some comments and suggestions after review.

Implement the functional states for the power domains:
- unify the API to use the functional states. pwrdm_set_next_fpwrst
  now is the function to control the power domains power and logic
  states,
- reorganize the powerdomain API in internal and external parts,
  in powerdomain.h [1]
- protect the power domain state change by a lock in
  pwrdm_set_next_fpwrst,
- introduce the functional states for power domains power states and
  logic power states, and the conversion functions between the
  functional and internal states,
- program the logic power state of power domains from the functional
  states, in pwrdm_set_next_fpwrst
- convert the OMAP2/3/4 PM code to use the updated API,
- provide the power domains statistics by functional states,
- provide ftrace tracepoints with the functional state,
- provide error logs in critical code, which makes the development
  easier.

Note: [1] the physical split of internal and external APIs into
      different header files is not part of this series, it comes as
      a separate patch set.


Based on mainline kernel 3.6.0-rc1.

Tested on OMAP3 Beagleboard, with suspend and cpuidle in RET and
OFF modes.


History:
 v5:
 - complete rework after review and suggestions,
 - improved locking on next state read/write; spinlock instead of mutex
 - added more error logging in critical code,

 v4:
 - reworked the code after internal review and testing with OMAP3&4 device
   OFF,
 - fixed the tracepoints generation code,
 - introduce a function that returns power domains achievable functional
   states, in order to return a valid state for power domains that only
   support some of the power states. Although it has been tested OK the
   code is in RFC state.

 v3:
 - fix a bug in OMAP3 cpuidle which prevented the IO wake-ups in PER

 v2:
 - add the logic power states,
 - provide the power domains statistics by functional states

 v1:
 - initial implementation, in RFC state


Jean Pihet (7):
  ARM: OMAP2+: PM: introduce power domains functional states
  ARM: OMAP2+: PM: introduce power domains achievable functional states
  ARM: OMAP2+: PM: add a lock to protect the powerdomains next state
  ARM: OMAP2+: PM: use the functional power states API
  ARM: OMAP2+: PM: use power domain functional state in stats counters
  ARM: OMAP2+: PM debug: trace the functional power domains states
  ARM: OMAP2+: PM: reorganize the powerdomain API in public and private
    parts

Nishanth Menon (1):
  ARM: OMAP2+: powerdomain: add error logs

 arch/arm/mach-omap2/cpuidle34xx.c          |   58 ++--
 arch/arm/mach-omap2/cpuidle44xx.c          |   24 +-
 arch/arm/mach-omap2/omap-hotplug.c         |    2 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c  |   39 ++--
 arch/arm/mach-omap2/pm-debug.c             |   15 +-
 arch/arm/mach-omap2/pm24xx.c               |   14 +-
 arch/arm/mach-omap2/pm34xx.c               |   79 +++---
 arch/arm/mach-omap2/pm44xx.c               |   24 +-
 arch/arm/mach-omap2/powerdomain-common.c   |   99 ++++++
 arch/arm/mach-omap2/powerdomain.c          |  456 +++++++++++++++++++++++++---
 arch/arm/mach-omap2/powerdomain.h          |  152 ++++++---
 arch/arm/mach-omap2/powerdomain2xxx_3xxx.c |    6 +
 arch/arm/mach-omap2/powerdomain44xx.c      |    3 +
 13 files changed, 753 insertions(+), 218 deletions(-)

-- 
1.7.7.6

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

* [PATCH 1/8] ARM: OMAP2+: PM: introduce power domains functional states
  2012-08-15 10:02 ` Jean Pihet
@ 2012-08-15 10:02   ` Jean Pihet
  -1 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Santosh Shilimkar, Nishanth Menon
  Cc: Jean Pihet

Introduce the functional states for power domains, which include
the power states and the logic states.
This patch provides the API functions to set and read the power
domains settings and to convert between the functional (i.e. logical)
and the internal (or registers) values.
OMAP2, OMAP3 and OMAP4 platforms are using common conversion routines.

In the new API only the function pwrdm_set_next_fpwrst shall be used
to change a power domain target state, along with the associated
PWRDM_FUNC_* and PWRDM_LOGIC_* macros as the state parameters.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomain-common.c   |   99 ++++++++++++
 arch/arm/mach-omap2/powerdomain.c          |  225 +++++++++++++++++++++++++++-
 arch/arm/mach-omap2/powerdomain.h          |   45 +++++-
 arch/arm/mach-omap2/powerdomain2xxx_3xxx.c |    6 +
 arch/arm/mach-omap2/powerdomain44xx.c      |    3 +
 5 files changed, 368 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c
index c0aeabf..a0fcee3 100644
--- a/arch/arm/mach-omap2/powerdomain-common.c
+++ b/arch/arm/mach-omap2/powerdomain-common.c
@@ -108,3 +108,102 @@ u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank)
 	return 0;
 }
 
+/**
+ * omap2_pwrdm_fpwrst_to_pwrst - Convert functional (i.e. logical) to
+ * internal (i.e. registers) values for the power domains states.
+ * @struct powerdomain * to convert the values for
+ * @fpwrst: functional power state
+ *
+ * Returns the internal power state value for the power domain, or
+ * -EINVAL in case of invalid parameters passed in.
+ */
+int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int ret;
+
+	switch (fpwrst) {
+	case PWRDM_FUNC_PWRST_ON:
+		ret = PWRDM_POWER_ON;
+		break;
+	case PWRDM_FUNC_PWRST_INACTIVE:
+		ret = PWRDM_POWER_INACTIVE;
+		break;
+	case PWRDM_FUNC_PWRST_CSWR:
+	case PWRDM_FUNC_PWRST_OSWR:
+		ret = PWRDM_POWER_RET;
+		break;
+	case PWRDM_FUNC_PWRST_OFF:
+		ret = PWRDM_POWER_OFF;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+/**
+ * omap2_pwrdm_fpwrst_to_logic_pwrst - Convert functional (i.e. logical) to
+ * internal (i.e. registers) values for the power domains logic states.
+ * @struct powerdomain * to convert the values for
+ * @pwrst: functional power state
+ *
+ * Returns the internal logic state value for the power domain, or
+ * -EINVAL in case of invalid parameters passed in.
+ */
+int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int ret;
+
+	switch (fpwrst) {
+	case PWRDM_FUNC_PWRST_ON:
+	case PWRDM_FUNC_PWRST_INACTIVE:
+	case PWRDM_FUNC_PWRST_CSWR:
+		ret = PWRDM_LOGIC_MEM_PWRST_RET;
+		break;
+	case PWRDM_FUNC_PWRST_OSWR:
+	case PWRDM_FUNC_PWRST_OFF:
+		ret = PWRDM_LOGIC_MEM_PWRST_OFF;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+/**
+ * omap2_pwrdm_pwrst_to_fpwrst - Convert internal (i.e. registers) to
+ * functional (i.e. logical) values for the power domains states.
+ * @struct powerdomain * to convert the values for
+ * @pwrst: internal power state
+ *
+ * Returns the functional power state value for the power domain, or
+ * -EINVAL in case of invalid parameters passed in.
+ */
+int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
+{
+	int ret;
+
+	switch (pwrst) {
+	case PWRDM_POWER_ON:
+		ret = PWRDM_FUNC_PWRST_ON;
+		break;
+	case PWRDM_POWER_INACTIVE:
+		ret = PWRDM_FUNC_PWRST_INACTIVE;
+		break;
+	case PWRDM_POWER_RET:
+		if (logic == PWRDM_LOGIC_MEM_PWRST_RET)
+			ret = PWRDM_FUNC_PWRST_CSWR;
+		else
+			ret = PWRDM_FUNC_PWRST_OSWR;
+		break;
+	case PWRDM_POWER_OFF:
+		ret = PWRDM_FUNC_PWRST_OFF;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 69b36e1..6fc3c84 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -1,7 +1,7 @@
 /*
  * OMAP powerdomain control
  *
- * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2011-2012 Texas Instruments, Inc.
  * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Written by Paul Walmsley
@@ -128,14 +128,14 @@ static void _update_logic_membank_counters(struct powerdomain *pwrdm)
 
 	prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
 	if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
-	    (prev_logic_pwrst == PWRDM_POWER_OFF))
+	    (prev_logic_pwrst == PWRDM_LOGIC_MEM_PWRST_OFF))
 		pwrdm->ret_logic_off_counter++;
 
 	for (i = 0; i < pwrdm->banks; i++) {
 		prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
 
 		if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
-		    (prev_mem_pwrst == PWRDM_POWER_OFF))
+		    (prev_mem_pwrst == PWRDM_LOGIC_MEM_PWRST_OFF))
 			pwrdm->ret_mem_off_counter[i]++;
 	}
 }
@@ -465,6 +465,171 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
 }
 
 /**
+ * pwrdm_fpwrst_to_pwrst - get the internal (i.e. registers) value mapped
+ * to the functional state
+ * @pwrdm: struct powerdomain * to query
+ * @fpwrst: functional power state
+ *
+ * Convert the functional power state to the platform specific power
+ * domain state value.
+ * Returns the internal power domain state value or -EINVAL in case
+ * of invalid parameters passed in.
+ */
+int pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int ret = fpwrst;
+
+	if ((!pwrdm) || (fpwrst >= PWRDM_MAX_FUNC_PWRSTS))
+		return -EINVAL;
+
+	if (arch_pwrdm && arch_pwrdm->pwrdm_fpwrst_to_pwrst)
+		ret = arch_pwrdm->pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst);
+
+	pr_debug("powerdomain: convert fwrst %0x to pwrst %0x for %s\n",
+		 fpwrst, ret, pwrdm->name);
+
+	return ret;
+}
+
+/**
+ * pwrdm_fpwrst_to_logic_pwrst - get the internal (i.e. registers) value
+ * of the logic state mapped to the functional state
+ * @pwrdm: struct powerdomain * to query
+ * @pwrst: functional power state
+ *
+ * Convert the functional power state to the platform specific power
+ * domain logic state value.
+ * Returns the internal power domain logic state value or -EINVAL in
+ * case of invalid parameters passed in.
+ */
+int pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int ret = fpwrst;
+
+	if ((!pwrdm) || (fpwrst >= PWRDM_MAX_FUNC_PWRSTS))
+		return -EINVAL;
+
+	if (arch_pwrdm && arch_pwrdm->pwrdm_fpwrst_to_logic_pwrst)
+		ret = arch_pwrdm->pwrdm_fpwrst_to_logic_pwrst(pwrdm, fpwrst);
+
+	pr_debug("powerdomain: convert fpwrst %0x to logic %0x pwrst for %s\n",
+		 fpwrst, ret, pwrdm->name);
+
+	return ret;
+}
+
+/**
+ * pwrdm_pwrst_to_fpwrst - get the functional (i.e. logical) value mapped
+ * to the internal state
+ * @pwrdm: struct powerdomain * to query
+ * @pwrst: internal power state
+ * @logic: internal logic state
+ *
+ * Convert the internal power state and logic power state
+ * to the power domain functional value.
+ * Returns the functional power domain state value or -EINVAL in case
+ * of invalid parameters passed in.
+ */
+int pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
+{
+	int ret = pwrst;
+
+	if ((!pwrdm) || (pwrst >= PWRDM_MAX_PWRSTS) ||
+	    (logic >= PWRDM_MAX_LOGIC_MEM_PWRST))
+		return -EINVAL;
+
+	while (!(pwrdm->pwrsts_logic_ret & (1 << logic))) {
+		if (logic == PWRDM_LOGIC_MEM_PWRST_RET)
+			break;
+		logic++;
+	}
+
+	if (arch_pwrdm && arch_pwrdm->pwrdm_pwrst_to_fpwrst)
+		ret = arch_pwrdm->pwrdm_pwrst_to_fpwrst(pwrdm, pwrst, logic);
+
+	pr_debug("powerdomain: convert pwrst (%0x,%0x) to fpwrst %0x for %s\n",
+		 pwrst, logic, ret, pwrdm->name);
+
+	return ret;
+}
+
+/* Types of sleep_switch used in pwrdm_set_next_fpwrst */
+#define FORCEWAKEUP_SWITCH	0
+#define LOWPOWERSTATE_SWITCH	1
+
+/**
+ * pwrdm_set_next_fpwrst - program next powerdomain functional power state
+ * @pwrdm: struct powerdomain * to set
+ * @fpwrst: power domain functional state, one of the PWRDM_FUNC_* macros
+ *
+ * This programs the pwrdm next functional state, sets the dependencies
+ * and waits for the state to be applied.
+ */
+int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
+			  enum pwrdm_func_state fpwrst)
+{
+	u8 curr_pwrst, next_pwrst;
+	int pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst);
+	int logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, fpwrst);
+	int sleep_switch = -1, ret = 0, hwsup = 0;
+
+	if (!pwrdm || IS_ERR(pwrdm) || (pwrst < 0) || (logic < 0)) {
+		pr_debug("%s: invalid params: pwrdm=%p, fpwrst=%0x\n",
+			 __func__, pwrdm, fpwrst);
+		return -EINVAL;
+	}
+
+	pr_debug("%s: set fpwrst %0x to pwrdm %s\n",
+		 __func__, fpwrst, pwrdm->name);
+
+	while (!(pwrdm->pwrsts & (1 << pwrst))) {
+		if (pwrst == PWRDM_POWER_OFF)
+			return ret;
+		pwrst--;
+	}
+
+	next_pwrst = pwrdm_read_next_pwrst(pwrdm);
+	if (next_pwrst == pwrst)
+		return ret;
+
+	curr_pwrst = pwrdm_read_pwrst(pwrdm);
+	if (curr_pwrst < PWRDM_POWER_ON) {
+		if ((curr_pwrst > pwrst) &&
+			(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
+			sleep_switch = LOWPOWERSTATE_SWITCH;
+		} else {
+			hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
+			clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+			sleep_switch = FORCEWAKEUP_SWITCH;
+		}
+	}
+
+	if (logic != pwrdm_read_logic_retst(pwrdm))
+		pwrdm_set_logic_retst(pwrdm, logic);
+
+	ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
+	if (ret)
+		pr_err("%s: unable to set power state of powerdomain: %s\n",
+		       __func__, pwrdm->name);
+
+	switch (sleep_switch) {
+	case FORCEWAKEUP_SWITCH:
+		if (hwsup)
+			clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+		else
+			clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
+		break;
+	case LOWPOWERSTATE_SWITCH:
+		pwrdm_set_lowpwrstchange(pwrdm);
+		pwrdm_wait_transition(pwrdm);
+		pwrdm_state_switch(pwrdm);
+		break;
+	}
+
+	return ret;
+}
+
+/**
  * pwrdm_set_next_pwrst - set next powerdomain power state
  * @pwrdm: struct powerdomain * to set
  * @pwrst: one of the PWRDM_POWER_* macros
@@ -521,6 +686,22 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
 }
 
 /**
+ * pwrdm_read_next_fpwrst - get next powerdomain functional power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain @pwrdm's next functional power state.
+ * Returns -EINVAL if the powerdomain pointer is null or returns
+ * the next power state upon success.
+ */
+int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
+{
+	int next_pwrst = pwrdm_read_next_pwrst(pwrdm);
+	int next_logic = pwrdm_read_logic_retst(pwrdm);
+
+	return pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic);
+}
+
+/**
  * pwrdm_read_pwrst - get current powerdomain power state
  * @pwrdm: struct powerdomain * to get power state
  *
@@ -546,6 +727,22 @@ int pwrdm_read_pwrst(struct powerdomain *pwrdm)
 }
 
 /**
+ * pwrdm_read_fpwrst - get current powerdomain functional power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain @pwrdm's current functional power state.
+ * Returns -EINVAL if the powerdomain pointer is null or returns
+ * the current power state upon success.
+ */
+int pwrdm_read_fpwrst(struct powerdomain *pwrdm)
+{
+	int pwrst = pwrdm_read_pwrst(pwrdm);
+	int logic = pwrdm_read_logic_pwrst(pwrdm);
+
+	return pwrdm_pwrst_to_fpwrst(pwrdm, pwrst, logic);
+}
+
+/**
  * pwrdm_read_prev_pwrst - get previous powerdomain power state
  * @pwrdm: struct powerdomain * to get previous power state
  *
@@ -567,9 +764,25 @@ int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
 }
 
 /**
+ * pwrdm_read_prev_fpwrst - get previous powerdomain functional power state
+ * @pwrdm: struct powerdomain * to get previous power state
+ *
+ * Return the powerdomain @pwrdm's previous functional power state.
+ * Returns -EINVAL if the powerdomain pointer is null or returns the
+ * previous power state upon success.
+ */
+int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm)
+{
+	int prev_pwrst = pwrdm_read_prev_pwrst(pwrdm);
+	int prev_logic = pwrdm_read_prev_logic_pwrst(pwrdm);
+
+	return pwrdm_pwrst_to_fpwrst(pwrdm, prev_pwrst, prev_logic);
+}
+
+/**
  * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
  * @pwrdm: struct powerdomain * to set
- * @pwrst: one of the PWRDM_POWER_* macros
+ * @pwrst: one of the PWRDM_LOGIC_MEM_PWRST_* macros
  *
  * Set the next power state @pwrst that the logic portion of the
  * powerdomain @pwrdm will enter when the powerdomain enters retention.
@@ -600,7 +813,7 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
  * pwrdm_set_mem_onst - set memory power state while powerdomain ON
  * @pwrdm: struct powerdomain * to set
  * @bank: memory bank number to set (0-3)
- * @pwrst: one of the PWRDM_POWER_* macros
+ * @pwrst: one of the PWRDM_LOGIC_MEM_PWRST_* macros
  *
  * Set the next power state @pwrst that memory bank @bank of the
  * powerdomain @pwrdm will enter when the powerdomain enters the ON
@@ -637,7 +850,7 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
  * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
  * @pwrdm: struct powerdomain * to set
  * @bank: memory bank number to set (0-3)
- * @pwrst: one of the PWRDM_POWER_* macros
+ * @pwrst: one of the PWRDM_LOGIC_MEM_PWRST_* macros
  *
  * Set the next power state @pwrst that memory bank @bank of the
  * powerdomain @pwrdm will enter when the powerdomain enters the
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index baee906..aa9f9b9 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -1,7 +1,7 @@
 /*
  * OMAP2/3/4 powerdomain control
  *
- * Copyright (C) 2007-2008, 2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2010, 2012 Texas Instruments, Inc.
  * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Paul Walmsley
@@ -9,9 +9,6 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- *
- * XXX This should be moved to the mach-omap2/ directory at the earliest
- * opportunity.
  */
 
 #ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_H
@@ -26,6 +23,26 @@
 
 #include "voltage.h"
 
+/* Powerdomain functional power states, used by the external API functions */
+enum pwrdm_func_state {
+	PWRDM_FUNC_PWRST_OFF		= 0x0,
+	PWRDM_FUNC_PWRST_OSWR,
+	PWRDM_FUNC_PWRST_CSWR,
+	PWRDM_FUNC_PWRST_INACTIVE,
+	PWRDM_FUNC_PWRST_ON,
+	PWRDM_MAX_FUNC_PWRSTS		/* Last value, used as the max value */
+};
+
+/*
+ * Powerdomains logic and memory functional power states,
+ * used by the external API functions
+ */
+enum pwrdm_logic_mem_state {
+	PWRDM_LOGIC_MEM_PWRST_OFF	= 0x0,
+	PWRDM_LOGIC_MEM_PWRST_RET,
+	PWRDM_MAX_LOGIC_MEM_PWRST	/* Last value, used as the max value */
+};
+
 /* Powerdomain basic power states */
 #define PWRDM_POWER_OFF		0x0
 #define PWRDM_POWER_RET		0x1
@@ -146,6 +163,12 @@ struct powerdomain {
 
 /**
  * struct pwrdm_ops - Arch specific function implementations
+ * @pwrdm_fpwrst_to_pwrst: Convert the pd functional power state to
+ *  the internal state
+ * @pwrdm_fpwrst_to_logic_pwrst: Convert the pd functional power state
+ *  to the internal logic state
+ * @pwrdm_pwrst_to_fpwrst: Convert the pd internal and logic power state to
+ *  the functional state
  * @pwrdm_set_next_pwrst: Set the target power state for a pd
  * @pwrdm_read_next_pwrst: Read the target power state set for a pd
  * @pwrdm_read_pwrst: Read the current power state of a pd
@@ -166,6 +189,11 @@ struct powerdomain {
  * @pwrdm_wait_transition: Wait for a pd state transition to complete
  */
 struct pwrdm_ops {
+	int	(*pwrdm_fpwrst_to_pwrst)(struct powerdomain *pwrdm, u8 fpwrst);
+	int	(*pwrdm_fpwrst_to_logic_pwrst)(struct powerdomain *pwrdm,
+					       u8 fpwrst);
+	int	(*pwrdm_pwrst_to_fpwrst)(struct powerdomain *pwrdm, u8 fpwrst,
+					 u8 logic);
 	int	(*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst);
 	int	(*pwrdm_read_next_pwrst)(struct powerdomain *pwrdm);
 	int	(*pwrdm_read_pwrst)(struct powerdomain *pwrdm);
@@ -206,6 +234,15 @@ struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
 
 int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
 
+int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
+			  enum pwrdm_func_state fpwrst);
+int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_read_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm);
+int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic);
+
 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_pwrst(struct powerdomain *pwrdm);
diff --git a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
index 0f0a9f1..aa883aa 100644
--- a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
@@ -210,6 +210,9 @@ static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
 }
 
 struct pwrdm_ops omap2_pwrdm_operations = {
+	.pwrdm_fpwrst_to_pwrst	= omap2_pwrdm_fpwrst_to_pwrst,
+	.pwrdm_fpwrst_to_logic_pwrst	= omap2_pwrdm_fpwrst_to_logic_pwrst,
+	.pwrdm_pwrst_to_fpwrst	= omap2_pwrdm_pwrst_to_fpwrst,
 	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
 	.pwrdm_read_pwrst	= omap2_pwrdm_read_pwrst,
@@ -222,6 +225,9 @@ struct pwrdm_ops omap2_pwrdm_operations = {
 };
 
 struct pwrdm_ops omap3_pwrdm_operations = {
+	.pwrdm_fpwrst_to_pwrst	= omap2_pwrdm_fpwrst_to_pwrst,
+	.pwrdm_fpwrst_to_logic_pwrst	= omap2_pwrdm_fpwrst_to_logic_pwrst,
+	.pwrdm_pwrst_to_fpwrst	= omap2_pwrdm_pwrst_to_fpwrst,
 	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
 	.pwrdm_read_pwrst	= omap2_pwrdm_read_pwrst,
diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c
index 601325b..8c37cc9 100644
--- a/arch/arm/mach-omap2/powerdomain44xx.c
+++ b/arch/arm/mach-omap2/powerdomain44xx.c
@@ -209,6 +209,9 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
 }
 
 struct pwrdm_ops omap4_pwrdm_operations = {
+	.pwrdm_fpwrst_to_pwrst	= omap2_pwrdm_fpwrst_to_pwrst,
+	.pwrdm_fpwrst_to_logic_pwrst	= omap2_pwrdm_fpwrst_to_logic_pwrst,
+	.pwrdm_pwrst_to_fpwrst	= omap2_pwrdm_pwrst_to_fpwrst,
 	.pwrdm_set_next_pwrst	= omap4_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst	= omap4_pwrdm_read_next_pwrst,
 	.pwrdm_read_pwrst	= omap4_pwrdm_read_pwrst,
-- 
1.7.7.6


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

* [PATCH 1/8] ARM: OMAP2+: PM: introduce power domains functional states
@ 2012-08-15 10:02   ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce the functional states for power domains, which include
the power states and the logic states.
This patch provides the API functions to set and read the power
domains settings and to convert between the functional (i.e. logical)
and the internal (or registers) values.
OMAP2, OMAP3 and OMAP4 platforms are using common conversion routines.

In the new API only the function pwrdm_set_next_fpwrst shall be used
to change a power domain target state, along with the associated
PWRDM_FUNC_* and PWRDM_LOGIC_* macros as the state parameters.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomain-common.c   |   99 ++++++++++++
 arch/arm/mach-omap2/powerdomain.c          |  225 +++++++++++++++++++++++++++-
 arch/arm/mach-omap2/powerdomain.h          |   45 +++++-
 arch/arm/mach-omap2/powerdomain2xxx_3xxx.c |    6 +
 arch/arm/mach-omap2/powerdomain44xx.c      |    3 +
 5 files changed, 368 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c
index c0aeabf..a0fcee3 100644
--- a/arch/arm/mach-omap2/powerdomain-common.c
+++ b/arch/arm/mach-omap2/powerdomain-common.c
@@ -108,3 +108,102 @@ u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank)
 	return 0;
 }
 
+/**
+ * omap2_pwrdm_fpwrst_to_pwrst - Convert functional (i.e. logical) to
+ * internal (i.e. registers) values for the power domains states.
+ * @struct powerdomain * to convert the values for
+ * @fpwrst: functional power state
+ *
+ * Returns the internal power state value for the power domain, or
+ * -EINVAL in case of invalid parameters passed in.
+ */
+int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int ret;
+
+	switch (fpwrst) {
+	case PWRDM_FUNC_PWRST_ON:
+		ret = PWRDM_POWER_ON;
+		break;
+	case PWRDM_FUNC_PWRST_INACTIVE:
+		ret = PWRDM_POWER_INACTIVE;
+		break;
+	case PWRDM_FUNC_PWRST_CSWR:
+	case PWRDM_FUNC_PWRST_OSWR:
+		ret = PWRDM_POWER_RET;
+		break;
+	case PWRDM_FUNC_PWRST_OFF:
+		ret = PWRDM_POWER_OFF;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+/**
+ * omap2_pwrdm_fpwrst_to_logic_pwrst - Convert functional (i.e. logical) to
+ * internal (i.e. registers) values for the power domains logic states.
+ * @struct powerdomain * to convert the values for
+ * @pwrst: functional power state
+ *
+ * Returns the internal logic state value for the power domain, or
+ * -EINVAL in case of invalid parameters passed in.
+ */
+int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int ret;
+
+	switch (fpwrst) {
+	case PWRDM_FUNC_PWRST_ON:
+	case PWRDM_FUNC_PWRST_INACTIVE:
+	case PWRDM_FUNC_PWRST_CSWR:
+		ret = PWRDM_LOGIC_MEM_PWRST_RET;
+		break;
+	case PWRDM_FUNC_PWRST_OSWR:
+	case PWRDM_FUNC_PWRST_OFF:
+		ret = PWRDM_LOGIC_MEM_PWRST_OFF;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+/**
+ * omap2_pwrdm_pwrst_to_fpwrst - Convert internal (i.e. registers) to
+ * functional (i.e. logical) values for the power domains states.
+ * @struct powerdomain * to convert the values for
+ * @pwrst: internal power state
+ *
+ * Returns the functional power state value for the power domain, or
+ * -EINVAL in case of invalid parameters passed in.
+ */
+int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
+{
+	int ret;
+
+	switch (pwrst) {
+	case PWRDM_POWER_ON:
+		ret = PWRDM_FUNC_PWRST_ON;
+		break;
+	case PWRDM_POWER_INACTIVE:
+		ret = PWRDM_FUNC_PWRST_INACTIVE;
+		break;
+	case PWRDM_POWER_RET:
+		if (logic == PWRDM_LOGIC_MEM_PWRST_RET)
+			ret = PWRDM_FUNC_PWRST_CSWR;
+		else
+			ret = PWRDM_FUNC_PWRST_OSWR;
+		break;
+	case PWRDM_POWER_OFF:
+		ret = PWRDM_FUNC_PWRST_OFF;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 69b36e1..6fc3c84 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -1,7 +1,7 @@
 /*
  * OMAP powerdomain control
  *
- * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2011-2012 Texas Instruments, Inc.
  * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Written by Paul Walmsley
@@ -128,14 +128,14 @@ static void _update_logic_membank_counters(struct powerdomain *pwrdm)
 
 	prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
 	if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
-	    (prev_logic_pwrst == PWRDM_POWER_OFF))
+	    (prev_logic_pwrst == PWRDM_LOGIC_MEM_PWRST_OFF))
 		pwrdm->ret_logic_off_counter++;
 
 	for (i = 0; i < pwrdm->banks; i++) {
 		prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
 
 		if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
-		    (prev_mem_pwrst == PWRDM_POWER_OFF))
+		    (prev_mem_pwrst == PWRDM_LOGIC_MEM_PWRST_OFF))
 			pwrdm->ret_mem_off_counter[i]++;
 	}
 }
@@ -465,6 +465,171 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
 }
 
 /**
+ * pwrdm_fpwrst_to_pwrst - get the internal (i.e. registers) value mapped
+ * to the functional state
+ * @pwrdm: struct powerdomain * to query
+ * @fpwrst: functional power state
+ *
+ * Convert the functional power state to the platform specific power
+ * domain state value.
+ * Returns the internal power domain state value or -EINVAL in case
+ * of invalid parameters passed in.
+ */
+int pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int ret = fpwrst;
+
+	if ((!pwrdm) || (fpwrst >= PWRDM_MAX_FUNC_PWRSTS))
+		return -EINVAL;
+
+	if (arch_pwrdm && arch_pwrdm->pwrdm_fpwrst_to_pwrst)
+		ret = arch_pwrdm->pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst);
+
+	pr_debug("powerdomain: convert fwrst %0x to pwrst %0x for %s\n",
+		 fpwrst, ret, pwrdm->name);
+
+	return ret;
+}
+
+/**
+ * pwrdm_fpwrst_to_logic_pwrst - get the internal (i.e. registers) value
+ * of the logic state mapped to the functional state
+ * @pwrdm: struct powerdomain * to query
+ * @pwrst: functional power state
+ *
+ * Convert the functional power state to the platform specific power
+ * domain logic state value.
+ * Returns the internal power domain logic state value or -EINVAL in
+ * case of invalid parameters passed in.
+ */
+int pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int ret = fpwrst;
+
+	if ((!pwrdm) || (fpwrst >= PWRDM_MAX_FUNC_PWRSTS))
+		return -EINVAL;
+
+	if (arch_pwrdm && arch_pwrdm->pwrdm_fpwrst_to_logic_pwrst)
+		ret = arch_pwrdm->pwrdm_fpwrst_to_logic_pwrst(pwrdm, fpwrst);
+
+	pr_debug("powerdomain: convert fpwrst %0x to logic %0x pwrst for %s\n",
+		 fpwrst, ret, pwrdm->name);
+
+	return ret;
+}
+
+/**
+ * pwrdm_pwrst_to_fpwrst - get the functional (i.e. logical) value mapped
+ * to the internal state
+ * @pwrdm: struct powerdomain * to query
+ * @pwrst: internal power state
+ * @logic: internal logic state
+ *
+ * Convert the internal power state and logic power state
+ * to the power domain functional value.
+ * Returns the functional power domain state value or -EINVAL in case
+ * of invalid parameters passed in.
+ */
+int pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
+{
+	int ret = pwrst;
+
+	if ((!pwrdm) || (pwrst >= PWRDM_MAX_PWRSTS) ||
+	    (logic >= PWRDM_MAX_LOGIC_MEM_PWRST))
+		return -EINVAL;
+
+	while (!(pwrdm->pwrsts_logic_ret & (1 << logic))) {
+		if (logic == PWRDM_LOGIC_MEM_PWRST_RET)
+			break;
+		logic++;
+	}
+
+	if (arch_pwrdm && arch_pwrdm->pwrdm_pwrst_to_fpwrst)
+		ret = arch_pwrdm->pwrdm_pwrst_to_fpwrst(pwrdm, pwrst, logic);
+
+	pr_debug("powerdomain: convert pwrst (%0x,%0x) to fpwrst %0x for %s\n",
+		 pwrst, logic, ret, pwrdm->name);
+
+	return ret;
+}
+
+/* Types of sleep_switch used in pwrdm_set_next_fpwrst */
+#define FORCEWAKEUP_SWITCH	0
+#define LOWPOWERSTATE_SWITCH	1
+
+/**
+ * pwrdm_set_next_fpwrst - program next powerdomain functional power state
+ * @pwrdm: struct powerdomain * to set
+ * @fpwrst: power domain functional state, one of the PWRDM_FUNC_* macros
+ *
+ * This programs the pwrdm next functional state, sets the dependencies
+ * and waits for the state to be applied.
+ */
+int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
+			  enum pwrdm_func_state fpwrst)
+{
+	u8 curr_pwrst, next_pwrst;
+	int pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst);
+	int logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, fpwrst);
+	int sleep_switch = -1, ret = 0, hwsup = 0;
+
+	if (!pwrdm || IS_ERR(pwrdm) || (pwrst < 0) || (logic < 0)) {
+		pr_debug("%s: invalid params: pwrdm=%p, fpwrst=%0x\n",
+			 __func__, pwrdm, fpwrst);
+		return -EINVAL;
+	}
+
+	pr_debug("%s: set fpwrst %0x to pwrdm %s\n",
+		 __func__, fpwrst, pwrdm->name);
+
+	while (!(pwrdm->pwrsts & (1 << pwrst))) {
+		if (pwrst == PWRDM_POWER_OFF)
+			return ret;
+		pwrst--;
+	}
+
+	next_pwrst = pwrdm_read_next_pwrst(pwrdm);
+	if (next_pwrst == pwrst)
+		return ret;
+
+	curr_pwrst = pwrdm_read_pwrst(pwrdm);
+	if (curr_pwrst < PWRDM_POWER_ON) {
+		if ((curr_pwrst > pwrst) &&
+			(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
+			sleep_switch = LOWPOWERSTATE_SWITCH;
+		} else {
+			hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
+			clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+			sleep_switch = FORCEWAKEUP_SWITCH;
+		}
+	}
+
+	if (logic != pwrdm_read_logic_retst(pwrdm))
+		pwrdm_set_logic_retst(pwrdm, logic);
+
+	ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
+	if (ret)
+		pr_err("%s: unable to set power state of powerdomain: %s\n",
+		       __func__, pwrdm->name);
+
+	switch (sleep_switch) {
+	case FORCEWAKEUP_SWITCH:
+		if (hwsup)
+			clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+		else
+			clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
+		break;
+	case LOWPOWERSTATE_SWITCH:
+		pwrdm_set_lowpwrstchange(pwrdm);
+		pwrdm_wait_transition(pwrdm);
+		pwrdm_state_switch(pwrdm);
+		break;
+	}
+
+	return ret;
+}
+
+/**
  * pwrdm_set_next_pwrst - set next powerdomain power state
  * @pwrdm: struct powerdomain * to set
  * @pwrst: one of the PWRDM_POWER_* macros
@@ -521,6 +686,22 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
 }
 
 /**
+ * pwrdm_read_next_fpwrst - get next powerdomain functional power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain @pwrdm's next functional power state.
+ * Returns -EINVAL if the powerdomain pointer is null or returns
+ * the next power state upon success.
+ */
+int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
+{
+	int next_pwrst = pwrdm_read_next_pwrst(pwrdm);
+	int next_logic = pwrdm_read_logic_retst(pwrdm);
+
+	return pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic);
+}
+
+/**
  * pwrdm_read_pwrst - get current powerdomain power state
  * @pwrdm: struct powerdomain * to get power state
  *
@@ -546,6 +727,22 @@ int pwrdm_read_pwrst(struct powerdomain *pwrdm)
 }
 
 /**
+ * pwrdm_read_fpwrst - get current powerdomain functional power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain @pwrdm's current functional power state.
+ * Returns -EINVAL if the powerdomain pointer is null or returns
+ * the current power state upon success.
+ */
+int pwrdm_read_fpwrst(struct powerdomain *pwrdm)
+{
+	int pwrst = pwrdm_read_pwrst(pwrdm);
+	int logic = pwrdm_read_logic_pwrst(pwrdm);
+
+	return pwrdm_pwrst_to_fpwrst(pwrdm, pwrst, logic);
+}
+
+/**
  * pwrdm_read_prev_pwrst - get previous powerdomain power state
  * @pwrdm: struct powerdomain * to get previous power state
  *
@@ -567,9 +764,25 @@ int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
 }
 
 /**
+ * pwrdm_read_prev_fpwrst - get previous powerdomain functional power state
+ * @pwrdm: struct powerdomain * to get previous power state
+ *
+ * Return the powerdomain @pwrdm's previous functional power state.
+ * Returns -EINVAL if the powerdomain pointer is null or returns the
+ * previous power state upon success.
+ */
+int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm)
+{
+	int prev_pwrst = pwrdm_read_prev_pwrst(pwrdm);
+	int prev_logic = pwrdm_read_prev_logic_pwrst(pwrdm);
+
+	return pwrdm_pwrst_to_fpwrst(pwrdm, prev_pwrst, prev_logic);
+}
+
+/**
  * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
  * @pwrdm: struct powerdomain * to set
- * @pwrst: one of the PWRDM_POWER_* macros
+ * @pwrst: one of the PWRDM_LOGIC_MEM_PWRST_* macros
  *
  * Set the next power state @pwrst that the logic portion of the
  * powerdomain @pwrdm will enter when the powerdomain enters retention.
@@ -600,7 +813,7 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
  * pwrdm_set_mem_onst - set memory power state while powerdomain ON
  * @pwrdm: struct powerdomain * to set
  * @bank: memory bank number to set (0-3)
- * @pwrst: one of the PWRDM_POWER_* macros
+ * @pwrst: one of the PWRDM_LOGIC_MEM_PWRST_* macros
  *
  * Set the next power state @pwrst that memory bank @bank of the
  * powerdomain @pwrdm will enter when the powerdomain enters the ON
@@ -637,7 +850,7 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
  * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
  * @pwrdm: struct powerdomain * to set
  * @bank: memory bank number to set (0-3)
- * @pwrst: one of the PWRDM_POWER_* macros
+ * @pwrst: one of the PWRDM_LOGIC_MEM_PWRST_* macros
  *
  * Set the next power state @pwrst that memory bank @bank of the
  * powerdomain @pwrdm will enter when the powerdomain enters the
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index baee906..aa9f9b9 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -1,7 +1,7 @@
 /*
  * OMAP2/3/4 powerdomain control
  *
- * Copyright (C) 2007-2008, 2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2010, 2012 Texas Instruments, Inc.
  * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Paul Walmsley
@@ -9,9 +9,6 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- *
- * XXX This should be moved to the mach-omap2/ directory at the earliest
- * opportunity.
  */
 
 #ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_H
@@ -26,6 +23,26 @@
 
 #include "voltage.h"
 
+/* Powerdomain functional power states, used by the external API functions */
+enum pwrdm_func_state {
+	PWRDM_FUNC_PWRST_OFF		= 0x0,
+	PWRDM_FUNC_PWRST_OSWR,
+	PWRDM_FUNC_PWRST_CSWR,
+	PWRDM_FUNC_PWRST_INACTIVE,
+	PWRDM_FUNC_PWRST_ON,
+	PWRDM_MAX_FUNC_PWRSTS		/* Last value, used as the max value */
+};
+
+/*
+ * Powerdomains logic and memory functional power states,
+ * used by the external API functions
+ */
+enum pwrdm_logic_mem_state {
+	PWRDM_LOGIC_MEM_PWRST_OFF	= 0x0,
+	PWRDM_LOGIC_MEM_PWRST_RET,
+	PWRDM_MAX_LOGIC_MEM_PWRST	/* Last value, used as the max value */
+};
+
 /* Powerdomain basic power states */
 #define PWRDM_POWER_OFF		0x0
 #define PWRDM_POWER_RET		0x1
@@ -146,6 +163,12 @@ struct powerdomain {
 
 /**
  * struct pwrdm_ops - Arch specific function implementations
+ * @pwrdm_fpwrst_to_pwrst: Convert the pd functional power state to
+ *  the internal state
+ * @pwrdm_fpwrst_to_logic_pwrst: Convert the pd functional power state
+ *  to the internal logic state
+ * @pwrdm_pwrst_to_fpwrst: Convert the pd internal and logic power state to
+ *  the functional state
  * @pwrdm_set_next_pwrst: Set the target power state for a pd
  * @pwrdm_read_next_pwrst: Read the target power state set for a pd
  * @pwrdm_read_pwrst: Read the current power state of a pd
@@ -166,6 +189,11 @@ struct powerdomain {
  * @pwrdm_wait_transition: Wait for a pd state transition to complete
  */
 struct pwrdm_ops {
+	int	(*pwrdm_fpwrst_to_pwrst)(struct powerdomain *pwrdm, u8 fpwrst);
+	int	(*pwrdm_fpwrst_to_logic_pwrst)(struct powerdomain *pwrdm,
+					       u8 fpwrst);
+	int	(*pwrdm_pwrst_to_fpwrst)(struct powerdomain *pwrdm, u8 fpwrst,
+					 u8 logic);
 	int	(*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst);
 	int	(*pwrdm_read_next_pwrst)(struct powerdomain *pwrdm);
 	int	(*pwrdm_read_pwrst)(struct powerdomain *pwrdm);
@@ -206,6 +234,15 @@ struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
 
 int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
 
+int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
+			  enum pwrdm_func_state fpwrst);
+int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_read_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm);
+int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic);
+
 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_pwrst(struct powerdomain *pwrdm);
diff --git a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
index 0f0a9f1..aa883aa 100644
--- a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
@@ -210,6 +210,9 @@ static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
 }
 
 struct pwrdm_ops omap2_pwrdm_operations = {
+	.pwrdm_fpwrst_to_pwrst	= omap2_pwrdm_fpwrst_to_pwrst,
+	.pwrdm_fpwrst_to_logic_pwrst	= omap2_pwrdm_fpwrst_to_logic_pwrst,
+	.pwrdm_pwrst_to_fpwrst	= omap2_pwrdm_pwrst_to_fpwrst,
 	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
 	.pwrdm_read_pwrst	= omap2_pwrdm_read_pwrst,
@@ -222,6 +225,9 @@ struct pwrdm_ops omap2_pwrdm_operations = {
 };
 
 struct pwrdm_ops omap3_pwrdm_operations = {
+	.pwrdm_fpwrst_to_pwrst	= omap2_pwrdm_fpwrst_to_pwrst,
+	.pwrdm_fpwrst_to_logic_pwrst	= omap2_pwrdm_fpwrst_to_logic_pwrst,
+	.pwrdm_pwrst_to_fpwrst	= omap2_pwrdm_pwrst_to_fpwrst,
 	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
 	.pwrdm_read_pwrst	= omap2_pwrdm_read_pwrst,
diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c
index 601325b..8c37cc9 100644
--- a/arch/arm/mach-omap2/powerdomain44xx.c
+++ b/arch/arm/mach-omap2/powerdomain44xx.c
@@ -209,6 +209,9 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
 }
 
 struct pwrdm_ops omap4_pwrdm_operations = {
+	.pwrdm_fpwrst_to_pwrst	= omap2_pwrdm_fpwrst_to_pwrst,
+	.pwrdm_fpwrst_to_logic_pwrst	= omap2_pwrdm_fpwrst_to_logic_pwrst,
+	.pwrdm_pwrst_to_fpwrst	= omap2_pwrdm_pwrst_to_fpwrst,
 	.pwrdm_set_next_pwrst	= omap4_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst	= omap4_pwrdm_read_next_pwrst,
 	.pwrdm_read_pwrst	= omap4_pwrdm_read_pwrst,
-- 
1.7.7.6

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

* [PATCH 2/8] ARM: OMAP2+: PM: introduce power domains achievable functional states
  2012-08-15 10:02 ` Jean Pihet
@ 2012-08-15 10:02   ` Jean Pihet
  -1 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Santosh Shilimkar, Nishanth Menon
  Cc: Jean Pihet, Tero Kristo

Note: the patch is in RFC state because the state machine for setting
the next power domain states needs more discussion. Validated on OMAP3&4
with cpuidle and suspend/resume, though.

Power domains have varied capabilities. When attempting a low power
state such as OFF/RET, a specific min requested state may not be
supported on the power domain. This is because a combination
of system power states where the parent PD's state is not in line
with expectation can result in system instabilities.

This patch provides a function that returns the achievable functional
power state for a power domain and its use by pwrdm_set_next_fpwrst.
The achievable power state is first looked for in the lower power
states in order to maximize the power savings, then if not found
in the higher power states.

Inspired from Tero's work on OMAP4 device OFF support, generalized
to the functional power states and reworked as per Nishant's
suggestions.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
Cc: Tero Kristo <t-kristo@ti.com>
Cc: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |  152 +++++++++++++++++++++++++++++++------
 arch/arm/mach-omap2/powerdomain.h |    1 +
 2 files changed, 130 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 6fc3c84..3a1f56c 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -199,6 +199,53 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
 	return 0;
 }
 
+/**
+ * Search down then up for a valid state from a list of allowed states.
+ * Used by pwrdm_get_achievable_fpwrst to look for allowed power and
+ * logic states for a powerdomain.
+ *
+ * @pwrsts: list of allowed states, defined as a bitmask
+ * @pwrst: initial state to be used as a starting point
+ * @min: minimum allowed state
+ * @max: maximum allowed state
+ *
+ * Returns the matching allowed state.
+ */
+static inline int _match_pwrst(u32 pwrsts, int pwrst, int min, int max)
+{
+	int found = 1, new_pwrst = pwrst;
+
+	/*
+	 * Search lower: if the requested state is not supported
+	 * try the lower states, stopping at the minimum allowed
+	 * state
+	 */
+	while (!(pwrsts & (1 << new_pwrst))) {
+		if (new_pwrst <= min) {
+			found = 0;
+			break;
+		}
+		new_pwrst--;
+	}
+
+	/*
+	 * Search higher: if no lower state found fallback to the higher
+	 * states, stopping at the maximum allowed state
+	 */
+	if (!found) {
+		new_pwrst = pwrst;
+		while (!(pwrsts & (1 << new_pwrst))) {
+			if (new_pwrst >= max) {
+				new_pwrst = max;
+				break;
+			}
+			new_pwrst++;
+		}
+	}
+
+	return new_pwrst;
+}
+
 /* Public functions */
 
 /**
@@ -553,6 +600,57 @@ int pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
 	return ret;
 }
 
+/**
+ * pwrdm_get_achievable_fpwrst() - Provide achievable functional state
+ * @pwrdm: struct powerdomain * to set
+ * @fpwrst: minimum functional state we would like to hit
+ * (one of the PWRDM_FUNC_* macros)
+ *
+ * Power domains have varied capabilities. When attempting a low power
+ * state such as OFF/RET, a specific min requested state may not be
+ * supported on the power domain. This is because a combination
+ * of system power states where the parent PD's state is not in line
+ * with expectation can result in system instabilities.
+ *
+ * The achievable power state is first looked for in the lower power
+ * states in order to maximize the power savings, then if not found
+ * in the higher power states.
+ *
+ * Returns the achievable functional power state, or -EINVAL in case of
+ * invalid parameters.
+ */
+int pwrdm_get_achievable_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst);
+	int logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, fpwrst);
+	int new_fpwrst, new_pwrst, new_logic;
+
+	if (!pwrdm || IS_ERR(pwrdm)) {
+		pr_debug("%s: invalid params: pwrdm=%p, fpwrst=%0x\n",
+			 __func__, pwrdm, fpwrst);
+		return -EINVAL;
+	}
+
+	if ((pwrst < 0) || (logic < 0)) {
+		pr_debug("%s: invalid params for pwrdm %s, fpwrst=%0x\n",
+			 __func__, pwrdm->name, fpwrst);
+		return PWRDM_FUNC_PWRST_ON;
+	}
+
+	new_pwrst = _match_pwrst(pwrdm->pwrsts, pwrst, PWRDM_POWER_OFF,
+				 PWRDM_POWER_ON);
+	new_logic = _match_pwrst(pwrdm->pwrsts_logic_ret, logic,
+				 PWRDM_LOGIC_MEM_PWRST_OFF,
+				 PWRDM_LOGIC_MEM_PWRST_RET);
+
+	new_fpwrst = pwrdm_pwrst_to_fpwrst(pwrdm, new_pwrst, new_logic);
+
+	pr_debug("%s(%s, fpwrst=%0x) returns %0x\n", __func__,
+		 pwrdm->name, fpwrst, new_fpwrst);
+
+	return new_fpwrst;
+}
+
 /* Types of sleep_switch used in pwrdm_set_next_fpwrst */
 #define FORCEWAKEUP_SWITCH	0
 #define LOWPOWERSTATE_SWITCH	1
@@ -562,34 +660,30 @@ int pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
  * @pwrdm: struct powerdomain * to set
  * @fpwrst: power domain functional state, one of the PWRDM_FUNC_* macros
  *
- * This programs the pwrdm next functional state, sets the dependencies
- * and waits for the state to be applied.
+ * This looks for the more suited (or achievable) next functional power
+ * state, programs it, sets the dependencies and waits for the state to
+ * be applied to the power domain.
  */
 int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 			  enum pwrdm_func_state fpwrst)
 {
-	u8 curr_pwrst, next_pwrst;
-	int pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst);
-	int logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, fpwrst);
 	int sleep_switch = -1, ret = 0, hwsup = 0;
+	int new_fpwrst, next_fpwrst, pwrst, logic;
+	u8 curr_pwrst;
 
-	if (!pwrdm || IS_ERR(pwrdm) || (pwrst < 0) || (logic < 0)) {
-		pr_debug("%s: invalid params: pwrdm=%p, fpwrst=%0x\n",
-			 __func__, pwrdm, fpwrst);
+	if (!pwrdm || IS_ERR(pwrdm)) {
+		pr_debug("%s: invalid params: pwrdm=%p\n", __func__, pwrdm);
 		return -EINVAL;
 	}
 
-	pr_debug("%s: set fpwrst %0x to pwrdm %s\n",
-		 __func__, fpwrst, pwrdm->name);
+	pr_debug("%s(%s, fpwrst=%0x)\n", __func__, pwrdm->name, fpwrst);
 
-	while (!(pwrdm->pwrsts & (1 << pwrst))) {
-		if (pwrst == PWRDM_POWER_OFF)
-			return ret;
-		pwrst--;
-	}
+	new_fpwrst = pwrdm_get_achievable_fpwrst(pwrdm, fpwrst);
+	pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, new_fpwrst);
+	logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, new_fpwrst);
 
-	next_pwrst = pwrdm_read_next_pwrst(pwrdm);
-	if (next_pwrst == pwrst)
+	next_fpwrst = pwrdm_read_next_fpwrst(pwrdm);
+	if (new_fpwrst == next_fpwrst)
 		return ret;
 
 	curr_pwrst = pwrdm_read_pwrst(pwrdm);
@@ -604,13 +698,25 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 		}
 	}
 
-	if (logic != pwrdm_read_logic_retst(pwrdm))
-		pwrdm_set_logic_retst(pwrdm, logic);
+	pr_debug("%s: set fpwrst %0x (%0x,%0x) to pwrdm %s\n",
+		 __func__, new_fpwrst, pwrst, logic, pwrdm->name);
+
+	/* Trace the pwrdm desired target state */
+	trace_power_domain_target(pwrdm->name, new_fpwrst,
+				  smp_processor_id());
+
+	/* Program next power state */
+	if (pwrst != pwrdm_fpwrst_to_pwrst(pwrdm, next_fpwrst)) {
+		ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
+		if (ret)
+			pr_err("%s: unable to set power state of powerdomain: %s\n",
+			       __func__, pwrdm->name);
+	}
 
-	ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
-	if (ret)
-		pr_err("%s: unable to set power state of powerdomain: %s\n",
-		       __func__, pwrdm->name);
+	/* Program RET logic state */
+	if ((pwrst == PWRDM_POWER_RET) &&
+	    (logic != pwrdm_fpwrst_to_logic_pwrst(pwrdm, next_fpwrst)))
+		pwrdm_set_logic_retst(pwrdm, logic);
 
 	switch (sleep_switch) {
 	case FORCEWAKEUP_SWITCH:
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index aa9f9b9..45c449d 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -239,6 +239,7 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm);
 int pwrdm_read_fpwrst(struct powerdomain *pwrdm);
 int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_get_achievable_fpwrst(struct powerdomain *pwrdm, u8 fpwrst);
 int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
 int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
 int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic);
-- 
1.7.7.6


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

* [PATCH 2/8] ARM: OMAP2+: PM: introduce power domains achievable functional states
@ 2012-08-15 10:02   ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

Note: the patch is in RFC state because the state machine for setting
the next power domain states needs more discussion. Validated on OMAP3&4
with cpuidle and suspend/resume, though.

Power domains have varied capabilities. When attempting a low power
state such as OFF/RET, a specific min requested state may not be
supported on the power domain. This is because a combination
of system power states where the parent PD's state is not in line
with expectation can result in system instabilities.

This patch provides a function that returns the achievable functional
power state for a power domain and its use by pwrdm_set_next_fpwrst.
The achievable power state is first looked for in the lower power
states in order to maximize the power savings, then if not found
in the higher power states.

Inspired from Tero's work on OMAP4 device OFF support, generalized
to the functional power states and reworked as per Nishant's
suggestions.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
Cc: Tero Kristo <t-kristo@ti.com>
Cc: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |  152 +++++++++++++++++++++++++++++++------
 arch/arm/mach-omap2/powerdomain.h |    1 +
 2 files changed, 130 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 6fc3c84..3a1f56c 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -199,6 +199,53 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
 	return 0;
 }
 
+/**
+ * Search down then up for a valid state from a list of allowed states.
+ * Used by pwrdm_get_achievable_fpwrst to look for allowed power and
+ * logic states for a powerdomain.
+ *
+ * @pwrsts: list of allowed states, defined as a bitmask
+ * @pwrst: initial state to be used as a starting point
+ * @min: minimum allowed state
+ * @max: maximum allowed state
+ *
+ * Returns the matching allowed state.
+ */
+static inline int _match_pwrst(u32 pwrsts, int pwrst, int min, int max)
+{
+	int found = 1, new_pwrst = pwrst;
+
+	/*
+	 * Search lower: if the requested state is not supported
+	 * try the lower states, stopping at the minimum allowed
+	 * state
+	 */
+	while (!(pwrsts & (1 << new_pwrst))) {
+		if (new_pwrst <= min) {
+			found = 0;
+			break;
+		}
+		new_pwrst--;
+	}
+
+	/*
+	 * Search higher: if no lower state found fallback to the higher
+	 * states, stopping@the maximum allowed state
+	 */
+	if (!found) {
+		new_pwrst = pwrst;
+		while (!(pwrsts & (1 << new_pwrst))) {
+			if (new_pwrst >= max) {
+				new_pwrst = max;
+				break;
+			}
+			new_pwrst++;
+		}
+	}
+
+	return new_pwrst;
+}
+
 /* Public functions */
 
 /**
@@ -553,6 +600,57 @@ int pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
 	return ret;
 }
 
+/**
+ * pwrdm_get_achievable_fpwrst() - Provide achievable functional state
+ * @pwrdm: struct powerdomain * to set
+ * @fpwrst: minimum functional state we would like to hit
+ * (one of the PWRDM_FUNC_* macros)
+ *
+ * Power domains have varied capabilities. When attempting a low power
+ * state such as OFF/RET, a specific min requested state may not be
+ * supported on the power domain. This is because a combination
+ * of system power states where the parent PD's state is not in line
+ * with expectation can result in system instabilities.
+ *
+ * The achievable power state is first looked for in the lower power
+ * states in order to maximize the power savings, then if not found
+ * in the higher power states.
+ *
+ * Returns the achievable functional power state, or -EINVAL in case of
+ * invalid parameters.
+ */
+int pwrdm_get_achievable_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
+{
+	int pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst);
+	int logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, fpwrst);
+	int new_fpwrst, new_pwrst, new_logic;
+
+	if (!pwrdm || IS_ERR(pwrdm)) {
+		pr_debug("%s: invalid params: pwrdm=%p, fpwrst=%0x\n",
+			 __func__, pwrdm, fpwrst);
+		return -EINVAL;
+	}
+
+	if ((pwrst < 0) || (logic < 0)) {
+		pr_debug("%s: invalid params for pwrdm %s, fpwrst=%0x\n",
+			 __func__, pwrdm->name, fpwrst);
+		return PWRDM_FUNC_PWRST_ON;
+	}
+
+	new_pwrst = _match_pwrst(pwrdm->pwrsts, pwrst, PWRDM_POWER_OFF,
+				 PWRDM_POWER_ON);
+	new_logic = _match_pwrst(pwrdm->pwrsts_logic_ret, logic,
+				 PWRDM_LOGIC_MEM_PWRST_OFF,
+				 PWRDM_LOGIC_MEM_PWRST_RET);
+
+	new_fpwrst = pwrdm_pwrst_to_fpwrst(pwrdm, new_pwrst, new_logic);
+
+	pr_debug("%s(%s, fpwrst=%0x) returns %0x\n", __func__,
+		 pwrdm->name, fpwrst, new_fpwrst);
+
+	return new_fpwrst;
+}
+
 /* Types of sleep_switch used in pwrdm_set_next_fpwrst */
 #define FORCEWAKEUP_SWITCH	0
 #define LOWPOWERSTATE_SWITCH	1
@@ -562,34 +660,30 @@ int pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
  * @pwrdm: struct powerdomain * to set
  * @fpwrst: power domain functional state, one of the PWRDM_FUNC_* macros
  *
- * This programs the pwrdm next functional state, sets the dependencies
- * and waits for the state to be applied.
+ * This looks for the more suited (or achievable) next functional power
+ * state, programs it, sets the dependencies and waits for the state to
+ * be applied to the power domain.
  */
 int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 			  enum pwrdm_func_state fpwrst)
 {
-	u8 curr_pwrst, next_pwrst;
-	int pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst);
-	int logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, fpwrst);
 	int sleep_switch = -1, ret = 0, hwsup = 0;
+	int new_fpwrst, next_fpwrst, pwrst, logic;
+	u8 curr_pwrst;
 
-	if (!pwrdm || IS_ERR(pwrdm) || (pwrst < 0) || (logic < 0)) {
-		pr_debug("%s: invalid params: pwrdm=%p, fpwrst=%0x\n",
-			 __func__, pwrdm, fpwrst);
+	if (!pwrdm || IS_ERR(pwrdm)) {
+		pr_debug("%s: invalid params: pwrdm=%p\n", __func__, pwrdm);
 		return -EINVAL;
 	}
 
-	pr_debug("%s: set fpwrst %0x to pwrdm %s\n",
-		 __func__, fpwrst, pwrdm->name);
+	pr_debug("%s(%s, fpwrst=%0x)\n", __func__, pwrdm->name, fpwrst);
 
-	while (!(pwrdm->pwrsts & (1 << pwrst))) {
-		if (pwrst == PWRDM_POWER_OFF)
-			return ret;
-		pwrst--;
-	}
+	new_fpwrst = pwrdm_get_achievable_fpwrst(pwrdm, fpwrst);
+	pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, new_fpwrst);
+	logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, new_fpwrst);
 
-	next_pwrst = pwrdm_read_next_pwrst(pwrdm);
-	if (next_pwrst == pwrst)
+	next_fpwrst = pwrdm_read_next_fpwrst(pwrdm);
+	if (new_fpwrst == next_fpwrst)
 		return ret;
 
 	curr_pwrst = pwrdm_read_pwrst(pwrdm);
@@ -604,13 +698,25 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 		}
 	}
 
-	if (logic != pwrdm_read_logic_retst(pwrdm))
-		pwrdm_set_logic_retst(pwrdm, logic);
+	pr_debug("%s: set fpwrst %0x (%0x,%0x) to pwrdm %s\n",
+		 __func__, new_fpwrst, pwrst, logic, pwrdm->name);
+
+	/* Trace the pwrdm desired target state */
+	trace_power_domain_target(pwrdm->name, new_fpwrst,
+				  smp_processor_id());
+
+	/* Program next power state */
+	if (pwrst != pwrdm_fpwrst_to_pwrst(pwrdm, next_fpwrst)) {
+		ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
+		if (ret)
+			pr_err("%s: unable to set power state of powerdomain: %s\n",
+			       __func__, pwrdm->name);
+	}
 
-	ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
-	if (ret)
-		pr_err("%s: unable to set power state of powerdomain: %s\n",
-		       __func__, pwrdm->name);
+	/* Program RET logic state */
+	if ((pwrst == PWRDM_POWER_RET) &&
+	    (logic != pwrdm_fpwrst_to_logic_pwrst(pwrdm, next_fpwrst)))
+		pwrdm_set_logic_retst(pwrdm, logic);
 
 	switch (sleep_switch) {
 	case FORCEWAKEUP_SWITCH:
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index aa9f9b9..45c449d 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -239,6 +239,7 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm);
 int pwrdm_read_fpwrst(struct powerdomain *pwrdm);
 int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_get_achievable_fpwrst(struct powerdomain *pwrdm, u8 fpwrst);
 int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
 int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
 int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic);
-- 
1.7.7.6

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

* [PATCH 3/8] ARM: OMAP2+: PM: add a lock to protect the powerdomains next state
  2012-08-15 10:02 ` Jean Pihet
@ 2012-08-15 10:02   ` Jean Pihet
  -1 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Santosh Shilimkar, Nishanth Menon
  Cc: Jean Pihet

pwrdm_set_next_fpwrst and pwrdm_read_next_fpwrst are intented
to be the only API to program and request the next state of a power
domain.
This patch protects the power domain next state settings and structs
from concurrent accesses by the use of a lock.

A spinlock is used since pwrdm_set_next_fpwrst and
pwrdm_read_next_fpwrst can be called from atomic context
(.i.e) either from cpuidle path or suspend path.

[ambresh@ti.com: reported the atomic context issue and suggested
to replace the mutex with a spinlock]

Signed-off-by: Jean Pihet <j-pihet@ti.com>
Reported-by: Ambresh K <ambresh@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |   36 +++++++++++++++++++++++++++++++-----
 arch/arm/mach-omap2/powerdomain.h |    3 +++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 3a1f56c..a8f7a81 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -102,6 +102,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 	INIT_LIST_HEAD(&pwrdm->voltdm_node);
 	voltdm_add_pwrdm(voltdm, pwrdm);
 
+	spin_lock_init(&pwrdm->lock);
 	list_add(&pwrdm->node, &pwrdm_list);
 
 	/* Initialize the powerdomain's state counter */
@@ -601,6 +602,22 @@ int pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
 }
 
 /**
+ * _pwrdm_read_next_fpwrst - get next powerdomain functional power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain @pwrdm's next functional power state.
+ * Returns -EINVAL if the powerdomain pointer is null or returns
+ * the next power state upon success.
+ */
+int _pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
+{
+	int next_pwrst = pwrdm_read_next_pwrst(pwrdm);
+	int next_logic = pwrdm_read_logic_retst(pwrdm);
+
+	return pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic);
+}
+
+/**
  * pwrdm_get_achievable_fpwrst() - Provide achievable functional state
  * @pwrdm: struct powerdomain * to set
  * @fpwrst: minimum functional state we would like to hit
@@ -670,6 +687,7 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 	int sleep_switch = -1, ret = 0, hwsup = 0;
 	int new_fpwrst, next_fpwrst, pwrst, logic;
 	u8 curr_pwrst;
+	unsigned long flags;
 
 	if (!pwrdm || IS_ERR(pwrdm)) {
 		pr_debug("%s: invalid params: pwrdm=%p\n", __func__, pwrdm);
@@ -678,13 +696,15 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 
 	pr_debug("%s(%s, fpwrst=%0x)\n", __func__, pwrdm->name, fpwrst);
 
+	spin_lock_irqsave(&pwrdm->lock, flags);
+
 	new_fpwrst = pwrdm_get_achievable_fpwrst(pwrdm, fpwrst);
 	pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, new_fpwrst);
 	logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, new_fpwrst);
 
-	next_fpwrst = pwrdm_read_next_fpwrst(pwrdm);
+	next_fpwrst = _pwrdm_read_next_fpwrst(pwrdm);
 	if (new_fpwrst == next_fpwrst)
-		return ret;
+		goto out;
 
 	curr_pwrst = pwrdm_read_pwrst(pwrdm);
 	if (curr_pwrst < PWRDM_POWER_ON) {
@@ -732,6 +752,8 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 		break;
 	}
 
+out:
+	spin_unlock_irqrestore(&pwrdm->lock, flags);
 	return ret;
 }
 
@@ -801,10 +823,14 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
  */
 int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
 {
-	int next_pwrst = pwrdm_read_next_pwrst(pwrdm);
-	int next_logic = pwrdm_read_logic_retst(pwrdm);
+	int ret;
+	unsigned long flags;
 
-	return pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic);
+	spin_lock_irqsave(&pwrdm->lock, flags);
+	ret = _pwrdm_read_next_fpwrst(pwrdm);
+	spin_unlock_irqrestore(&pwrdm->lock, flags);
+
+	return ret;
 }
 
 /**
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 45c449d..23b9da9 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/list.h>
 
+#include <linux/spinlock.h>
 #include <linux/atomic.h>
 
 #include <plat/cpu.h>
@@ -109,6 +110,7 @@ struct powerdomain;
  * @pwrdm_clkdms: Clockdomains in this powerdomain
  * @node: list_head linking all powerdomains
  * @voltdm_node: list_head linking all powerdomains in a voltagedomain
+ * @lock: powerdomain next state registers protection lock
  * @pwrstctrl_offs: (AM33XX only) XXX_PWRSTCTRL reg offset from prcm_offs
  * @pwrstst_offs: (AM33XX only) XXX_PWRSTST reg offset from prcm_offs
  * @logicretstate_mask: (AM33XX only) mask for logic retention bitfield
@@ -142,6 +144,7 @@ struct powerdomain {
 	struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
 	struct list_head node;
 	struct list_head voltdm_node;
+	spinlock_t lock;
 	int state;
 	unsigned state_counter[PWRDM_MAX_PWRSTS];
 	unsigned ret_logic_off_counter;
-- 
1.7.7.6


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

* [PATCH 3/8] ARM: OMAP2+: PM: add a lock to protect the powerdomains next state
@ 2012-08-15 10:02   ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

pwrdm_set_next_fpwrst and pwrdm_read_next_fpwrst are intented
to be the only API to program and request the next state of a power
domain.
This patch protects the power domain next state settings and structs
from concurrent accesses by the use of a lock.

A spinlock is used since pwrdm_set_next_fpwrst and
pwrdm_read_next_fpwrst can be called from atomic context
(.i.e) either from cpuidle path or suspend path.

[ambresh at ti.com: reported the atomic context issue and suggested
to replace the mutex with a spinlock]

Signed-off-by: Jean Pihet <j-pihet@ti.com>
Reported-by: Ambresh K <ambresh@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |   36 +++++++++++++++++++++++++++++++-----
 arch/arm/mach-omap2/powerdomain.h |    3 +++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 3a1f56c..a8f7a81 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -102,6 +102,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 	INIT_LIST_HEAD(&pwrdm->voltdm_node);
 	voltdm_add_pwrdm(voltdm, pwrdm);
 
+	spin_lock_init(&pwrdm->lock);
 	list_add(&pwrdm->node, &pwrdm_list);
 
 	/* Initialize the powerdomain's state counter */
@@ -601,6 +602,22 @@ int pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic)
 }
 
 /**
+ * _pwrdm_read_next_fpwrst - get next powerdomain functional power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain @pwrdm's next functional power state.
+ * Returns -EINVAL if the powerdomain pointer is null or returns
+ * the next power state upon success.
+ */
+int _pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
+{
+	int next_pwrst = pwrdm_read_next_pwrst(pwrdm);
+	int next_logic = pwrdm_read_logic_retst(pwrdm);
+
+	return pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic);
+}
+
+/**
  * pwrdm_get_achievable_fpwrst() - Provide achievable functional state
  * @pwrdm: struct powerdomain * to set
  * @fpwrst: minimum functional state we would like to hit
@@ -670,6 +687,7 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 	int sleep_switch = -1, ret = 0, hwsup = 0;
 	int new_fpwrst, next_fpwrst, pwrst, logic;
 	u8 curr_pwrst;
+	unsigned long flags;
 
 	if (!pwrdm || IS_ERR(pwrdm)) {
 		pr_debug("%s: invalid params: pwrdm=%p\n", __func__, pwrdm);
@@ -678,13 +696,15 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 
 	pr_debug("%s(%s, fpwrst=%0x)\n", __func__, pwrdm->name, fpwrst);
 
+	spin_lock_irqsave(&pwrdm->lock, flags);
+
 	new_fpwrst = pwrdm_get_achievable_fpwrst(pwrdm, fpwrst);
 	pwrst = pwrdm_fpwrst_to_pwrst(pwrdm, new_fpwrst);
 	logic = pwrdm_fpwrst_to_logic_pwrst(pwrdm, new_fpwrst);
 
-	next_fpwrst = pwrdm_read_next_fpwrst(pwrdm);
+	next_fpwrst = _pwrdm_read_next_fpwrst(pwrdm);
 	if (new_fpwrst == next_fpwrst)
-		return ret;
+		goto out;
 
 	curr_pwrst = pwrdm_read_pwrst(pwrdm);
 	if (curr_pwrst < PWRDM_POWER_ON) {
@@ -732,6 +752,8 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 		break;
 	}
 
+out:
+	spin_unlock_irqrestore(&pwrdm->lock, flags);
 	return ret;
 }
 
@@ -801,10 +823,14 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
  */
 int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
 {
-	int next_pwrst = pwrdm_read_next_pwrst(pwrdm);
-	int next_logic = pwrdm_read_logic_retst(pwrdm);
+	int ret;
+	unsigned long flags;
 
-	return pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic);
+	spin_lock_irqsave(&pwrdm->lock, flags);
+	ret = _pwrdm_read_next_fpwrst(pwrdm);
+	spin_unlock_irqrestore(&pwrdm->lock, flags);
+
+	return ret;
 }
 
 /**
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 45c449d..23b9da9 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/list.h>
 
+#include <linux/spinlock.h>
 #include <linux/atomic.h>
 
 #include <plat/cpu.h>
@@ -109,6 +110,7 @@ struct powerdomain;
  * @pwrdm_clkdms: Clockdomains in this powerdomain
  * @node: list_head linking all powerdomains
  * @voltdm_node: list_head linking all powerdomains in a voltagedomain
+ * @lock: powerdomain next state registers protection lock
  * @pwrstctrl_offs: (AM33XX only) XXX_PWRSTCTRL reg offset from prcm_offs
  * @pwrstst_offs: (AM33XX only) XXX_PWRSTST reg offset from prcm_offs
  * @logicretstate_mask: (AM33XX only) mask for logic retention bitfield
@@ -142,6 +144,7 @@ struct powerdomain {
 	struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
 	struct list_head node;
 	struct list_head voltdm_node;
+	spinlock_t lock;
 	int state;
 	unsigned state_counter[PWRDM_MAX_PWRSTS];
 	unsigned ret_logic_off_counter;
-- 
1.7.7.6

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

* [PATCH 4/8] ARM: OMAP2+: PM: use the functional power states API
  2012-08-15 10:02 ` Jean Pihet
@ 2012-08-15 10:02   ` Jean Pihet
  -1 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Santosh Shilimkar, Nishanth Menon
  Cc: Jean Pihet

Use the functional power states as the API to control power
domains:
- use the PWRDM_FUNC_PWRST_* and PWRDM_LOGIC_MEM_PWRST_*
  macros for the power states and logic settings,
- the pwrdm_set_next_fpwrst function, which controls
  the power states and logic settings of power domains, shall
  be used instead of pwrdm_set_next_pwrst to program the power
  domains next states.

Note: the internal code for power domains state management still
uses the internal power states.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c         |   58 +++++++++++-----------
 arch/arm/mach-omap2/cpuidle44xx.c         |   24 +++------
 arch/arm/mach-omap2/omap-hotplug.c        |    2 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   39 +++++++-------
 arch/arm/mach-omap2/pm24xx.c              |   14 ++---
 arch/arm/mach-omap2/pm34xx.c              |   79 +++++++++++++++--------------
 arch/arm/mach-omap2/pm44xx.c              |   24 +++------
 arch/arm/mach-omap2/powerdomain.c         |    2 +-
 8 files changed, 116 insertions(+), 126 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index f2a49a4..4ca37d2 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -44,32 +44,32 @@ struct omap3_idle_statedata {
 
 static struct omap3_idle_statedata omap3_idle_data[] = {
 	{
-		.mpu_state = PWRDM_POWER_ON,
-		.core_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_ON,
+		.core_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.mpu_state = PWRDM_POWER_ON,
-		.core_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_ON,
+		.core_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.mpu_state = PWRDM_POWER_RET,
-		.core_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_CSWR,
+		.core_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.mpu_state = PWRDM_POWER_OFF,
-		.core_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_OFF,
+		.core_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.mpu_state = PWRDM_POWER_RET,
-		.core_state = PWRDM_POWER_RET,
+		.mpu_state = PWRDM_FUNC_PWRST_CSWR,
+		.core_state = PWRDM_FUNC_PWRST_CSWR,
 	},
 	{
-		.mpu_state = PWRDM_POWER_OFF,
-		.core_state = PWRDM_POWER_RET,
+		.mpu_state = PWRDM_FUNC_PWRST_OFF,
+		.core_state = PWRDM_FUNC_PWRST_CSWR,
 	},
 	{
-		.mpu_state = PWRDM_POWER_OFF,
-		.core_state = PWRDM_POWER_OFF,
+		.mpu_state = PWRDM_FUNC_PWRST_OFF,
+		.core_state = PWRDM_FUNC_PWRST_OFF,
 	},
 };
 
@@ -84,8 +84,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
 
 	local_fiq_disable();
 
-	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
-	pwrdm_set_next_pwrst(core_pd, core_state);
+	pwrdm_set_next_fpwrst(mpu_pd, mpu_state);
+	pwrdm_set_next_fpwrst(core_pd, core_state);
 
 	if (omap_irq_pending() || need_resched())
 		goto return_sleep_time;
@@ -100,7 +100,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
 	 * Call idle CPU PM enter notifier chain so that
 	 * VFP context is saved.
 	 */
-	if (mpu_state == PWRDM_POWER_OFF)
+	if (mpu_state == PWRDM_FUNC_PWRST_OFF)
 		cpu_pm_enter();
 
 	/* Execute ARM wfi */
@@ -110,7 +110,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
 	 * Call idle CPU PM enter notifier chain to restore
 	 * VFP context.
 	 */
-	if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)
+	if (pwrdm_read_prev_fpwrst(mpu_pd) == PWRDM_FUNC_PWRST_OFF)
 		cpu_pm_exit();
 
 	/* Re-allow idle for C1 */
@@ -159,20 +159,20 @@ static int next_valid_state(struct cpuidle_device *dev,
 			    struct cpuidle_driver *drv, int index)
 {
 	struct omap3_idle_statedata *cx = &omap3_idle_data[index];
-	u32 mpu_deepest_state = PWRDM_POWER_RET;
-	u32 core_deepest_state = PWRDM_POWER_RET;
+	u32 mpu_deepest_state = PWRDM_FUNC_PWRST_CSWR;
+	u32 core_deepest_state = PWRDM_FUNC_PWRST_CSWR;
 	int idx;
 	int next_index = 0; /* C1 is the default value */
 
 	if (enable_off_mode) {
-		mpu_deepest_state = PWRDM_POWER_OFF;
+		mpu_deepest_state = PWRDM_FUNC_PWRST_OFF;
 		/*
 		 * Erratum i583: valable for ES rev < Es1.2 on 3630.
 		 * CORE OFF mode is not supported in a stable form, restrict
 		 * instead the CORE state to RET.
 		 */
 		if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
-			core_deepest_state = PWRDM_POWER_OFF;
+			core_deepest_state = PWRDM_FUNC_PWRST_OFF;
 	}
 
 	/* Check if current state is valid */
@@ -218,7 +218,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 	 * Use only C1 if CAM is active.
 	 * CAM does not have wakeup capability in OMAP3.
 	 */
-	if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON)
+	if (pwrdm_read_fpwrst(cam_pd) == PWRDM_FUNC_PWRST_ON)
 		new_state_idx = drv->safe_state_index;
 	else
 		new_state_idx = next_valid_state(dev, drv, index);
@@ -234,7 +234,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 	/* Program PER state */
 	cx = &omap3_idle_data[new_state_idx];
 	core_next_state = cx->core_state;
-	per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
+	per_next_state = per_saved_state = pwrdm_read_next_fpwrst(per_pd);
 	if (new_state_idx == 0) {
 		/* In C1 do not allow PER state lower than CORE state */
 		if (per_next_state < core_next_state)
@@ -244,20 +244,20 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 		 * Prevent PER OFF if CORE is not in RETention or OFF as this
 		 * would disable PER wakeups completely.
 		 */
-		if ((per_next_state == PWRDM_POWER_OFF) &&
-		    (core_next_state > PWRDM_POWER_RET))
-			per_next_state = PWRDM_POWER_RET;
+		if ((per_next_state == PWRDM_FUNC_PWRST_OFF) &&
+		    (core_next_state > PWRDM_FUNC_PWRST_CSWR))
+			per_next_state = PWRDM_FUNC_PWRST_CSWR;
 	}
 
 	/* Are we changing PER target state? */
 	if (per_next_state != per_saved_state)
-		pwrdm_set_next_pwrst(per_pd, per_next_state);
+		pwrdm_set_next_fpwrst(per_pd, per_next_state);
 
 	ret = omap3_enter_idle(dev, drv, new_state_idx);
 
 	/* Restore original PER state if it was modified */
 	if (per_next_state != per_saved_state)
-		pwrdm_set_next_pwrst(per_pd, per_saved_state);
+		pwrdm_set_next_fpwrst(per_pd, per_saved_state);
 
 	return ret;
 }
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index ee05e19..e4af351 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -26,25 +26,21 @@
 /* Machine specific information */
 struct omap4_idle_statedata {
 	u32 cpu_state;
-	u32 mpu_logic_state;
 	u32 mpu_state;
 };
 
 static struct omap4_idle_statedata omap4_idle_data[] = {
 	{
-		.cpu_state = PWRDM_POWER_ON,
-		.mpu_state = PWRDM_POWER_ON,
-		.mpu_logic_state = PWRDM_POWER_RET,
+		.cpu_state = PWRDM_FUNC_PWRST_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.cpu_state = PWRDM_POWER_OFF,
-		.mpu_state = PWRDM_POWER_RET,
-		.mpu_logic_state = PWRDM_POWER_RET,
+		.cpu_state = PWRDM_FUNC_PWRST_OFF,
+		.mpu_state = PWRDM_FUNC_PWRST_CSWR,
 	},
 	{
-		.cpu_state = PWRDM_POWER_OFF,
-		.mpu_state = PWRDM_POWER_RET,
-		.mpu_logic_state = PWRDM_POWER_OFF,
+		.cpu_state = PWRDM_FUNC_PWRST_OFF,
+		.mpu_state = PWRDM_FUNC_PWRST_OSWR,
 	},
 };
 
@@ -91,7 +87,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
 	 * out of coherency and in OFF mode.
 	 */
 	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
-		while (pwrdm_read_pwrst(cpu_pd[1]) != PWRDM_POWER_OFF) {
+		while (pwrdm_read_fpwrst(cpu_pd[1]) != PWRDM_FUNC_PWRST_OFF) {
 			cpu_relax();
 
 			/*
@@ -116,15 +112,13 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
 	cpu_pm_enter();
 
 	if (dev->cpu == 0) {
-		pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
-		omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+		pwrdm_set_next_fpwrst(mpu_pd, cx->mpu_state);
 
 		/*
 		 * Call idle CPU cluster PM enter notifier chain
 		 * to save GIC and wakeupgen context.
 		 */
-		if ((cx->mpu_state == PWRDM_POWER_RET) &&
-			(cx->mpu_logic_state == PWRDM_POWER_OFF))
+		if (cx->mpu_state == PWRDM_FUNC_PWRST_OSWR)
 				cpu_cluster_pm_enter();
 	}
 
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 414083b..be53726 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -58,7 +58,7 @@ void __ref platform_cpu_die(unsigned int cpu)
 		/*
 		 * Enter into low power state
 		 */
-		omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
+		omap4_hotplug_cpu(cpu, PWRDM_FUNC_PWRST_OFF);
 
 		if (omap_secure_apis_support())
 			boot_cpu = omap_read_auxcoreboot0();
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 637a1bd..f73c0c8 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -86,14 +86,14 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
 }
 
 /*
- * Set the CPUx powerdomain's previous power state
+ * Set the CPUx powerdomain's next functional power state
  */
 static inline void set_cpu_next_pwrst(unsigned int cpu_id,
 				unsigned int power_state)
 {
 	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
 
-	pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
+	pwrdm_set_next_fpwrst(pm_info->pwrdm, power_state);
 }
 
 /*
@@ -103,7 +103,7 @@ static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id)
 {
 	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
 
-	return pwrdm_read_prev_pwrst(pm_info->pwrdm);
+	return pwrdm_read_prev_fpwrst(pm_info->pwrdm);
 }
 
 /*
@@ -125,14 +125,15 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
 	u32 scu_pwr_st;
 
 	switch (cpu_state) {
-	case PWRDM_POWER_RET:
+	case PWRDM_FUNC_PWRST_OSWR:
+	case PWRDM_FUNC_PWRST_CSWR:
 		scu_pwr_st = SCU_PM_DORMANT;
 		break;
-	case PWRDM_POWER_OFF:
+	case PWRDM_FUNC_PWRST_OFF:
 		scu_pwr_st = SCU_PM_POWEROFF;
 		break;
-	case PWRDM_POWER_ON:
-	case PWRDM_POWER_INACTIVE:
+	case PWRDM_FUNC_PWRST_ON:
+	case PWRDM_FUNC_PWRST_INACTIVE:
 	default:
 		scu_pwr_st = SCU_PM_NORMAL;
 		break;
@@ -236,14 +237,15 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		return -ENXIO;
 
 	switch (power_state) {
-	case PWRDM_POWER_ON:
-	case PWRDM_POWER_INACTIVE:
+	case PWRDM_FUNC_PWRST_ON:
+	case PWRDM_FUNC_PWRST_INACTIVE:
 		save_state = 0;
 		break;
-	case PWRDM_POWER_OFF:
+	case PWRDM_FUNC_PWRST_OFF:
 		save_state = 1;
 		break;
-	case PWRDM_POWER_RET:
+	case PWRDM_FUNC_PWRST_OSWR:
+	case PWRDM_FUNC_PWRST_CSWR:
 	default:
 		/*
 		 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
@@ -259,11 +261,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 
 	/*
 	 * Check MPUSS next state and save interrupt controller if needed.
-	 * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
+	 * In MPUSS OSWR or device OFF, interrupt controller context is lost.
 	 */
 	mpuss_clear_prev_logic_pwrst();
-	if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
-		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
+	if (pwrdm_read_next_fpwrst(mpuss_pd) == PWRDM_FUNC_PWRST_OSWR)
 		save_state = 2;
 
 	cpu_clear_prev_logic_pwrst(cpu);
@@ -285,7 +286,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	 * domain transition
 	 */
 	wakeup_cpu = smp_processor_id();
-	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
+	set_cpu_next_pwrst(wakeup_cpu, PWRDM_FUNC_PWRST_ON);
 
 	pwrdm_post_transition(NULL);
 
@@ -304,7 +305,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		return -ENXIO;
 
-	if (power_state == PWRDM_POWER_OFF)
+	if (power_state == PWRDM_FUNC_PWRST_OFF)
 		cpu_state = 1;
 
 	clear_cpu_prev_pwrst(cpu);
@@ -319,7 +320,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 	 */
 	omap4_finish_suspend(cpu_state);
 
-	set_cpu_next_pwrst(cpu, PWRDM_POWER_ON);
+	set_cpu_next_pwrst(cpu, PWRDM_FUNC_PWRST_ON);
 	return 0;
 }
 
@@ -354,7 +355,7 @@ int __init omap4_mpuss_init(void)
 	cpu_clear_prev_logic_pwrst(0);
 
 	/* Initialise CPU0 power domain state to ON */
-	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+	pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON);
 
 	pm_info = &per_cpu(omap4_pm_info, 0x1);
 	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
@@ -371,7 +372,7 @@ int __init omap4_mpuss_init(void)
 	cpu_clear_prev_logic_pwrst(1);
 
 	/* Initialise CPU1 power domain state to ON */
-	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+	pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON);
 
 	mpuss_pd = pwrdm_lookup("mpu_pwrdm");
 	if (!mpuss_pd) {
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 2edeffc..f012bb4 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -93,8 +93,7 @@ static int omap2_enter_full_retention(void)
 	 * Set MPU powerdomain's next power state to RETENTION;
 	 * preserve logic state during retention
 	 */
-	pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
-	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
+	pwrdm_set_next_fpwrst(mpu_pwrdm, PWRDM_FUNC_PWRST_CSWR);
 
 	/* Workaround to kill USB */
 	l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
@@ -248,26 +247,25 @@ static void __init prcm_setup_regs(void)
 	 */
 	num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm);
 	for (i = 0; i < num_mem_banks; i++)
-		pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET);
+		pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_LOGIC_MEM_PWRST_RET);
 
 	/* Set CORE powerdomain's next power state to RETENTION */
-	pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);
+	pwrdm_set_next_fpwrst(core_pwrdm, PWRDM_FUNC_PWRST_CSWR);
 
 	/*
 	 * Set MPU powerdomain's next power state to RETENTION;
 	 * preserve logic state during retention
 	 */
-	pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
-	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
+	pwrdm_set_next_fpwrst(mpu_pwrdm, PWRDM_FUNC_PWRST_CSWR);
 
 	/* Force-power down DSP, GFX powerdomains */
 
 	pwrdm = clkdm_get_pwrdm(dsp_clkdm);
-	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
+	pwrdm_set_next_fpwrst(pwrdm, PWRDM_FUNC_PWRST_OFF);
 	clkdm_sleep(dsp_clkdm);
 
 	pwrdm = clkdm_get_pwrdm(gfx_clkdm);
-	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
+	pwrdm_set_next_fpwrst(pwrdm, PWRDM_FUNC_PWRST_OFF);
 	clkdm_sleep(gfx_clkdm);
 
 	/* Enable hardware-supervised idle for all clkdms */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index e4fc88c..2049b7f 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -111,7 +111,7 @@ static void omap3_core_restore_context(void)
 static void omap3_save_secure_ram_context(void)
 {
 	u32 ret;
-	int mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+	int mpu_next_state = pwrdm_read_next_fpwrst(mpu_pwrdm);
 
 	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
 		/*
@@ -119,10 +119,10 @@ static void omap3_save_secure_ram_context(void)
 		 * otherwise the WFI executed inside the ROM code
 		 * will hang the system.
 		 */
-		pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
+		pwrdm_set_next_fpwrst(mpu_pwrdm, PWRDM_FUNC_PWRST_ON);
 		ret = _omap_save_secure_sram((u32 *)
 				__pa(omap3_secure_ram_storage));
-		pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state);
+		pwrdm_set_next_fpwrst(mpu_pwrdm, mpu_next_state);
 		/* Following is for error tracking, it should not happen */
 		if (ret) {
 			pr_err("save_secure_sram() returns %08x\n", ret);
@@ -241,21 +241,23 @@ void omap_sram_idle(void)
 	/* save_state = 2 => Only L2 lost */
 	/* save_state = 3 => L1, L2 and logic lost */
 	int save_state = 0;
-	int mpu_next_state = PWRDM_POWER_ON;
-	int per_next_state = PWRDM_POWER_ON;
-	int core_next_state = PWRDM_POWER_ON;
+	int mpu_next_state = PWRDM_FUNC_PWRST_ON;
+	int per_next_state = PWRDM_FUNC_PWRST_ON;
+	int core_next_state = PWRDM_FUNC_PWRST_ON;
 	int per_going_off;
 	int core_prev_state;
 	u32 sdrc_pwr = 0;
 
-	mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+	mpu_next_state = pwrdm_read_next_fpwrst(mpu_pwrdm);
 	switch (mpu_next_state) {
-	case PWRDM_POWER_ON:
-	case PWRDM_POWER_RET:
+	case PWRDM_FUNC_PWRST_ON:
+	case PWRDM_FUNC_PWRST_INACTIVE:
+	case PWRDM_FUNC_PWRST_CSWR:
 		/* No need to save context */
 		save_state = 0;
 		break;
-	case PWRDM_POWER_OFF:
+	case PWRDM_FUNC_PWRST_OSWR:
+	case PWRDM_FUNC_PWRST_OFF:
 		save_state = 3;
 		break;
 	default:
@@ -265,29 +267,30 @@ void omap_sram_idle(void)
 	}
 
 	/* NEON control */
-	if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
-		pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state);
+	if (pwrdm_read_fpwrst(neon_pwrdm) == PWRDM_FUNC_PWRST_ON)
+		pwrdm_set_next_fpwrst(neon_pwrdm, mpu_next_state);
 
 	/* Enable IO-PAD and IO-CHAIN wakeups */
-	per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
-	core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
+	per_next_state = pwrdm_read_next_fpwrst(per_pwrdm);
+	core_next_state = pwrdm_read_next_fpwrst(core_pwrdm);
 
-	if (mpu_next_state < PWRDM_POWER_ON) {
+	if (mpu_next_state < PWRDM_FUNC_PWRST_ON) {
 		pwrdm_pre_transition(mpu_pwrdm);
 		pwrdm_pre_transition(neon_pwrdm);
 	}
 
 	/* PER */
-	if (per_next_state < PWRDM_POWER_ON) {
+	if (per_next_state < PWRDM_FUNC_PWRST_ON) {
 		pwrdm_pre_transition(per_pwrdm);
-		per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
+		per_going_off = (per_next_state == PWRDM_FUNC_PWRST_OFF) ?
+				1 : 0;
 		omap2_gpio_prepare_for_idle(per_going_off);
 	}
 
 	/* CORE */
-	if (core_next_state < PWRDM_POWER_ON) {
+	if (core_next_state < PWRDM_FUNC_PWRST_ON) {
 		pwrdm_pre_transition(core_pwrdm);
-		if (core_next_state == PWRDM_POWER_OFF) {
+		if (core_next_state == PWRDM_FUNC_PWRST_OFF) {
 			omap3_core_save_context();
 			omap3_cm_save_context();
 		}
@@ -304,7 +307,7 @@ void omap_sram_idle(void)
 	if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
 	    (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
 	     omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
-	    core_next_state == PWRDM_POWER_OFF)
+	    core_next_state == PWRDM_FUNC_PWRST_OFF)
 		sdrc_pwr = sdrc_read_reg(SDRC_POWER);
 
 	/*
@@ -323,19 +326,19 @@ void omap_sram_idle(void)
 	if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
 	    (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
 	     omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
-	    core_next_state == PWRDM_POWER_OFF)
+	    core_next_state == PWRDM_FUNC_PWRST_OFF)
 		sdrc_write_reg(sdrc_pwr, SDRC_POWER);
 
 	/* CORE */
-	if (core_next_state < PWRDM_POWER_ON) {
-		core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
-		if (core_prev_state == PWRDM_POWER_OFF) {
+	if (core_next_state < PWRDM_FUNC_PWRST_ON) {
+		core_prev_state = pwrdm_read_prev_fpwrst(core_pwrdm);
+		if (core_prev_state == PWRDM_FUNC_PWRST_OFF) {
 			omap3_core_restore_context();
 			omap3_cm_restore_context();
 			omap3_sram_restore_context();
 			omap2_sms_restore_context();
 		}
-		if (core_next_state == PWRDM_POWER_OFF)
+		if (core_next_state == PWRDM_FUNC_PWRST_OFF)
 			omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
 					       OMAP3430_GR_MOD,
 					       OMAP3_PRM_VOLTCTRL_OFFSET);
@@ -344,12 +347,12 @@ void omap_sram_idle(void)
 	omap3_intc_resume_idle();
 
 	/* PER */
-	if (per_next_state < PWRDM_POWER_ON) {
+	if (per_next_state < PWRDM_FUNC_PWRST_ON) {
 		omap2_gpio_resume_after_idle();
 		pwrdm_post_transition(per_pwrdm);
 	}
 
-	if (mpu_next_state < PWRDM_POWER_ON) {
+	if (mpu_next_state < PWRDM_FUNC_PWRST_ON) {
 		pwrdm_post_transition(mpu_pwrdm);
 		pwrdm_post_transition(neon_pwrdm);
 	}
@@ -382,10 +385,10 @@ static int omap3_pm_suspend(void)
 
 	/* Read current next_pwrsts */
 	list_for_each_entry(pwrst, &pwrst_list, node)
-		pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
+		pwrst->saved_state = pwrdm_read_next_fpwrst(pwrst->pwrdm);
 	/* Set ones wanted by suspend */
 	list_for_each_entry(pwrst, &pwrst_list, node) {
-		if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
+		if (pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state))
 			goto restore;
 		if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
 			goto restore;
@@ -398,14 +401,14 @@ static int omap3_pm_suspend(void)
 restore:
 	/* Restore next_pwrsts */
 	list_for_each_entry(pwrst, &pwrst_list, node) {
-		state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
+		state = pwrdm_read_prev_fpwrst(pwrst->pwrdm);
 		if (state > pwrst->next_state) {
 			pr_info("Powerdomain (%s) didn't enter "
 				"target state %d\n",
 			       pwrst->pwrdm->name, pwrst->next_state);
 			ret = -1;
 		}
-		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
+		pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->saved_state);
 	}
 	if (ret)
 		pr_err("Could not enter target state in pm_suspend\n");
@@ -577,21 +580,21 @@ void omap3_pm_off_mode_enable(int enable)
 	u32 state;
 
 	if (enable)
-		state = PWRDM_POWER_OFF;
+		state = PWRDM_FUNC_PWRST_OFF;
 	else
-		state = PWRDM_POWER_RET;
+		state = PWRDM_FUNC_PWRST_CSWR;
 
 	list_for_each_entry(pwrst, &pwrst_list, node) {
 		if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
 				pwrst->pwrdm == core_pwrdm &&
-				state == PWRDM_POWER_OFF) {
-			pwrst->next_state = PWRDM_POWER_RET;
+				state == PWRDM_FUNC_PWRST_OFF) {
+			pwrst->next_state = PWRDM_FUNC_PWRST_CSWR;
 			pr_warn("%s: Core OFF disabled due to errata i583\n",
 				__func__);
 		} else {
 			pwrst->next_state = state;
 		}
-		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+		pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state);
 	}
 }
 
@@ -630,13 +633,13 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+	pwrst->next_state = PWRDM_FUNC_PWRST_CSWR;
 	list_add(&pwrst->node, &pwrst_list);
 
 	if (pwrdm_has_hdwr_sar(pwrdm))
 		pwrdm_enable_hdwr_sar(pwrdm);
 
-	return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+	return pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state);
 }
 
 /*
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index ea24174..3d31880 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -28,7 +28,6 @@ struct power_state {
 	u32 next_state;
 #ifdef CONFIG_SUSPEND
 	u32 saved_state;
-	u32 saved_logic_state;
 #endif
 	struct list_head node;
 };
@@ -43,16 +42,12 @@ static int omap4_pm_suspend(void)
 	u32 cpu_id = smp_processor_id();
 
 	/* Save current powerdomain state */
-	list_for_each_entry(pwrst, &pwrst_list, node) {
-		pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
-		pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm);
-	}
+	list_for_each_entry(pwrst, &pwrst_list, node)
+		pwrst->saved_state = pwrdm_read_next_fpwrst(pwrst->pwrdm);
 
 	/* Set targeted power domain states by suspend */
-	list_for_each_entry(pwrst, &pwrst_list, node) {
-		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
-		pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF);
-	}
+	list_for_each_entry(pwrst, &pwrst_list, node)
+		pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state);
 
 	/*
 	 * For MPUSS to hit power domain retention(CSWR or OSWR),
@@ -63,19 +58,18 @@ static int omap4_pm_suspend(void)
 	 * domain CSWR is not supported by hardware.
 	 * More details can be found in OMAP4430 TRM section 4.3.4.2.
 	 */
-	omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF);
+	omap4_enter_lowpower(cpu_id, PWRDM_FUNC_PWRST_OFF);
 
 	/* Restore next powerdomain state */
 	list_for_each_entry(pwrst, &pwrst_list, node) {
-		state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
+		state = pwrdm_read_prev_fpwrst(pwrst->pwrdm);
 		if (state > pwrst->next_state) {
 			pr_info("Powerdomain (%s) didn't enter "
 			       "target state %d\n",
 			       pwrst->pwrdm->name, pwrst->next_state);
 			ret = -1;
 		}
-		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
-		pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state);
+		pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->saved_state);
 	}
 	if (ret)
 		pr_crit("Could not enter target state in pm_suspend\n");
@@ -113,10 +107,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 		return -ENOMEM;
 
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+	pwrst->next_state = PWRDM_FUNC_PWRST_CSWR;
 	list_add(&pwrst->node, &pwrst_list);
 
-	return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+	return pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state);
 }
 
 /**
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index a8f7a81..1f9ed2c 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -317,7 +317,7 @@ int pwrdm_complete_init(void)
 		return -EACCES;
 
 	list_for_each_entry(temp_p, &pwrdm_list, node)
-		pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
+		pwrdm_set_next_fpwrst(temp_p, PWRDM_FUNC_PWRST_ON);
 
 	return 0;
 }
-- 
1.7.7.6


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

* [PATCH 4/8] ARM: OMAP2+: PM: use the functional power states API
@ 2012-08-15 10:02   ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

Use the functional power states as the API to control power
domains:
- use the PWRDM_FUNC_PWRST_* and PWRDM_LOGIC_MEM_PWRST_*
  macros for the power states and logic settings,
- the pwrdm_set_next_fpwrst function, which controls
  the power states and logic settings of power domains, shall
  be used instead of pwrdm_set_next_pwrst to program the power
  domains next states.

Note: the internal code for power domains state management still
uses the internal power states.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c         |   58 +++++++++++-----------
 arch/arm/mach-omap2/cpuidle44xx.c         |   24 +++------
 arch/arm/mach-omap2/omap-hotplug.c        |    2 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   39 +++++++-------
 arch/arm/mach-omap2/pm24xx.c              |   14 ++---
 arch/arm/mach-omap2/pm34xx.c              |   79 +++++++++++++++--------------
 arch/arm/mach-omap2/pm44xx.c              |   24 +++------
 arch/arm/mach-omap2/powerdomain.c         |    2 +-
 8 files changed, 116 insertions(+), 126 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index f2a49a4..4ca37d2 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -44,32 +44,32 @@ struct omap3_idle_statedata {
 
 static struct omap3_idle_statedata omap3_idle_data[] = {
 	{
-		.mpu_state = PWRDM_POWER_ON,
-		.core_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_ON,
+		.core_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.mpu_state = PWRDM_POWER_ON,
-		.core_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_ON,
+		.core_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.mpu_state = PWRDM_POWER_RET,
-		.core_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_CSWR,
+		.core_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.mpu_state = PWRDM_POWER_OFF,
-		.core_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_OFF,
+		.core_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.mpu_state = PWRDM_POWER_RET,
-		.core_state = PWRDM_POWER_RET,
+		.mpu_state = PWRDM_FUNC_PWRST_CSWR,
+		.core_state = PWRDM_FUNC_PWRST_CSWR,
 	},
 	{
-		.mpu_state = PWRDM_POWER_OFF,
-		.core_state = PWRDM_POWER_RET,
+		.mpu_state = PWRDM_FUNC_PWRST_OFF,
+		.core_state = PWRDM_FUNC_PWRST_CSWR,
 	},
 	{
-		.mpu_state = PWRDM_POWER_OFF,
-		.core_state = PWRDM_POWER_OFF,
+		.mpu_state = PWRDM_FUNC_PWRST_OFF,
+		.core_state = PWRDM_FUNC_PWRST_OFF,
 	},
 };
 
@@ -84,8 +84,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
 
 	local_fiq_disable();
 
-	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
-	pwrdm_set_next_pwrst(core_pd, core_state);
+	pwrdm_set_next_fpwrst(mpu_pd, mpu_state);
+	pwrdm_set_next_fpwrst(core_pd, core_state);
 
 	if (omap_irq_pending() || need_resched())
 		goto return_sleep_time;
@@ -100,7 +100,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
 	 * Call idle CPU PM enter notifier chain so that
 	 * VFP context is saved.
 	 */
-	if (mpu_state == PWRDM_POWER_OFF)
+	if (mpu_state == PWRDM_FUNC_PWRST_OFF)
 		cpu_pm_enter();
 
 	/* Execute ARM wfi */
@@ -110,7 +110,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
 	 * Call idle CPU PM enter notifier chain to restore
 	 * VFP context.
 	 */
-	if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)
+	if (pwrdm_read_prev_fpwrst(mpu_pd) == PWRDM_FUNC_PWRST_OFF)
 		cpu_pm_exit();
 
 	/* Re-allow idle for C1 */
@@ -159,20 +159,20 @@ static int next_valid_state(struct cpuidle_device *dev,
 			    struct cpuidle_driver *drv, int index)
 {
 	struct omap3_idle_statedata *cx = &omap3_idle_data[index];
-	u32 mpu_deepest_state = PWRDM_POWER_RET;
-	u32 core_deepest_state = PWRDM_POWER_RET;
+	u32 mpu_deepest_state = PWRDM_FUNC_PWRST_CSWR;
+	u32 core_deepest_state = PWRDM_FUNC_PWRST_CSWR;
 	int idx;
 	int next_index = 0; /* C1 is the default value */
 
 	if (enable_off_mode) {
-		mpu_deepest_state = PWRDM_POWER_OFF;
+		mpu_deepest_state = PWRDM_FUNC_PWRST_OFF;
 		/*
 		 * Erratum i583: valable for ES rev < Es1.2 on 3630.
 		 * CORE OFF mode is not supported in a stable form, restrict
 		 * instead the CORE state to RET.
 		 */
 		if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
-			core_deepest_state = PWRDM_POWER_OFF;
+			core_deepest_state = PWRDM_FUNC_PWRST_OFF;
 	}
 
 	/* Check if current state is valid */
@@ -218,7 +218,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 	 * Use only C1 if CAM is active.
 	 * CAM does not have wakeup capability in OMAP3.
 	 */
-	if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON)
+	if (pwrdm_read_fpwrst(cam_pd) == PWRDM_FUNC_PWRST_ON)
 		new_state_idx = drv->safe_state_index;
 	else
 		new_state_idx = next_valid_state(dev, drv, index);
@@ -234,7 +234,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 	/* Program PER state */
 	cx = &omap3_idle_data[new_state_idx];
 	core_next_state = cx->core_state;
-	per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
+	per_next_state = per_saved_state = pwrdm_read_next_fpwrst(per_pd);
 	if (new_state_idx == 0) {
 		/* In C1 do not allow PER state lower than CORE state */
 		if (per_next_state < core_next_state)
@@ -244,20 +244,20 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 		 * Prevent PER OFF if CORE is not in RETention or OFF as this
 		 * would disable PER wakeups completely.
 		 */
-		if ((per_next_state == PWRDM_POWER_OFF) &&
-		    (core_next_state > PWRDM_POWER_RET))
-			per_next_state = PWRDM_POWER_RET;
+		if ((per_next_state == PWRDM_FUNC_PWRST_OFF) &&
+		    (core_next_state > PWRDM_FUNC_PWRST_CSWR))
+			per_next_state = PWRDM_FUNC_PWRST_CSWR;
 	}
 
 	/* Are we changing PER target state? */
 	if (per_next_state != per_saved_state)
-		pwrdm_set_next_pwrst(per_pd, per_next_state);
+		pwrdm_set_next_fpwrst(per_pd, per_next_state);
 
 	ret = omap3_enter_idle(dev, drv, new_state_idx);
 
 	/* Restore original PER state if it was modified */
 	if (per_next_state != per_saved_state)
-		pwrdm_set_next_pwrst(per_pd, per_saved_state);
+		pwrdm_set_next_fpwrst(per_pd, per_saved_state);
 
 	return ret;
 }
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index ee05e19..e4af351 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -26,25 +26,21 @@
 /* Machine specific information */
 struct omap4_idle_statedata {
 	u32 cpu_state;
-	u32 mpu_logic_state;
 	u32 mpu_state;
 };
 
 static struct omap4_idle_statedata omap4_idle_data[] = {
 	{
-		.cpu_state = PWRDM_POWER_ON,
-		.mpu_state = PWRDM_POWER_ON,
-		.mpu_logic_state = PWRDM_POWER_RET,
+		.cpu_state = PWRDM_FUNC_PWRST_ON,
+		.mpu_state = PWRDM_FUNC_PWRST_ON,
 	},
 	{
-		.cpu_state = PWRDM_POWER_OFF,
-		.mpu_state = PWRDM_POWER_RET,
-		.mpu_logic_state = PWRDM_POWER_RET,
+		.cpu_state = PWRDM_FUNC_PWRST_OFF,
+		.mpu_state = PWRDM_FUNC_PWRST_CSWR,
 	},
 	{
-		.cpu_state = PWRDM_POWER_OFF,
-		.mpu_state = PWRDM_POWER_RET,
-		.mpu_logic_state = PWRDM_POWER_OFF,
+		.cpu_state = PWRDM_FUNC_PWRST_OFF,
+		.mpu_state = PWRDM_FUNC_PWRST_OSWR,
 	},
 };
 
@@ -91,7 +87,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
 	 * out of coherency and in OFF mode.
 	 */
 	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
-		while (pwrdm_read_pwrst(cpu_pd[1]) != PWRDM_POWER_OFF) {
+		while (pwrdm_read_fpwrst(cpu_pd[1]) != PWRDM_FUNC_PWRST_OFF) {
 			cpu_relax();
 
 			/*
@@ -116,15 +112,13 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
 	cpu_pm_enter();
 
 	if (dev->cpu == 0) {
-		pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
-		omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+		pwrdm_set_next_fpwrst(mpu_pd, cx->mpu_state);
 
 		/*
 		 * Call idle CPU cluster PM enter notifier chain
 		 * to save GIC and wakeupgen context.
 		 */
-		if ((cx->mpu_state == PWRDM_POWER_RET) &&
-			(cx->mpu_logic_state == PWRDM_POWER_OFF))
+		if (cx->mpu_state == PWRDM_FUNC_PWRST_OSWR)
 				cpu_cluster_pm_enter();
 	}
 
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 414083b..be53726 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -58,7 +58,7 @@ void __ref platform_cpu_die(unsigned int cpu)
 		/*
 		 * Enter into low power state
 		 */
-		omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
+		omap4_hotplug_cpu(cpu, PWRDM_FUNC_PWRST_OFF);
 
 		if (omap_secure_apis_support())
 			boot_cpu = omap_read_auxcoreboot0();
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 637a1bd..f73c0c8 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -86,14 +86,14 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
 }
 
 /*
- * Set the CPUx powerdomain's previous power state
+ * Set the CPUx powerdomain's next functional power state
  */
 static inline void set_cpu_next_pwrst(unsigned int cpu_id,
 				unsigned int power_state)
 {
 	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
 
-	pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
+	pwrdm_set_next_fpwrst(pm_info->pwrdm, power_state);
 }
 
 /*
@@ -103,7 +103,7 @@ static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id)
 {
 	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
 
-	return pwrdm_read_prev_pwrst(pm_info->pwrdm);
+	return pwrdm_read_prev_fpwrst(pm_info->pwrdm);
 }
 
 /*
@@ -125,14 +125,15 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
 	u32 scu_pwr_st;
 
 	switch (cpu_state) {
-	case PWRDM_POWER_RET:
+	case PWRDM_FUNC_PWRST_OSWR:
+	case PWRDM_FUNC_PWRST_CSWR:
 		scu_pwr_st = SCU_PM_DORMANT;
 		break;
-	case PWRDM_POWER_OFF:
+	case PWRDM_FUNC_PWRST_OFF:
 		scu_pwr_st = SCU_PM_POWEROFF;
 		break;
-	case PWRDM_POWER_ON:
-	case PWRDM_POWER_INACTIVE:
+	case PWRDM_FUNC_PWRST_ON:
+	case PWRDM_FUNC_PWRST_INACTIVE:
 	default:
 		scu_pwr_st = SCU_PM_NORMAL;
 		break;
@@ -236,14 +237,15 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		return -ENXIO;
 
 	switch (power_state) {
-	case PWRDM_POWER_ON:
-	case PWRDM_POWER_INACTIVE:
+	case PWRDM_FUNC_PWRST_ON:
+	case PWRDM_FUNC_PWRST_INACTIVE:
 		save_state = 0;
 		break;
-	case PWRDM_POWER_OFF:
+	case PWRDM_FUNC_PWRST_OFF:
 		save_state = 1;
 		break;
-	case PWRDM_POWER_RET:
+	case PWRDM_FUNC_PWRST_OSWR:
+	case PWRDM_FUNC_PWRST_CSWR:
 	default:
 		/*
 		 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
@@ -259,11 +261,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 
 	/*
 	 * Check MPUSS next state and save interrupt controller if needed.
-	 * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
+	 * In MPUSS OSWR or device OFF, interrupt controller context is lost.
 	 */
 	mpuss_clear_prev_logic_pwrst();
-	if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
-		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
+	if (pwrdm_read_next_fpwrst(mpuss_pd) == PWRDM_FUNC_PWRST_OSWR)
 		save_state = 2;
 
 	cpu_clear_prev_logic_pwrst(cpu);
@@ -285,7 +286,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	 * domain transition
 	 */
 	wakeup_cpu = smp_processor_id();
-	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
+	set_cpu_next_pwrst(wakeup_cpu, PWRDM_FUNC_PWRST_ON);
 
 	pwrdm_post_transition(NULL);
 
@@ -304,7 +305,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		return -ENXIO;
 
-	if (power_state == PWRDM_POWER_OFF)
+	if (power_state == PWRDM_FUNC_PWRST_OFF)
 		cpu_state = 1;
 
 	clear_cpu_prev_pwrst(cpu);
@@ -319,7 +320,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 	 */
 	omap4_finish_suspend(cpu_state);
 
-	set_cpu_next_pwrst(cpu, PWRDM_POWER_ON);
+	set_cpu_next_pwrst(cpu, PWRDM_FUNC_PWRST_ON);
 	return 0;
 }
 
@@ -354,7 +355,7 @@ int __init omap4_mpuss_init(void)
 	cpu_clear_prev_logic_pwrst(0);
 
 	/* Initialise CPU0 power domain state to ON */
-	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+	pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON);
 
 	pm_info = &per_cpu(omap4_pm_info, 0x1);
 	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
@@ -371,7 +372,7 @@ int __init omap4_mpuss_init(void)
 	cpu_clear_prev_logic_pwrst(1);
 
 	/* Initialise CPU1 power domain state to ON */
-	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
+	pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON);
 
 	mpuss_pd = pwrdm_lookup("mpu_pwrdm");
 	if (!mpuss_pd) {
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 2edeffc..f012bb4 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -93,8 +93,7 @@ static int omap2_enter_full_retention(void)
 	 * Set MPU powerdomain's next power state to RETENTION;
 	 * preserve logic state during retention
 	 */
-	pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
-	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
+	pwrdm_set_next_fpwrst(mpu_pwrdm, PWRDM_FUNC_PWRST_CSWR);
 
 	/* Workaround to kill USB */
 	l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
@@ -248,26 +247,25 @@ static void __init prcm_setup_regs(void)
 	 */
 	num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm);
 	for (i = 0; i < num_mem_banks; i++)
-		pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET);
+		pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_LOGIC_MEM_PWRST_RET);
 
 	/* Set CORE powerdomain's next power state to RETENTION */
-	pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);
+	pwrdm_set_next_fpwrst(core_pwrdm, PWRDM_FUNC_PWRST_CSWR);
 
 	/*
 	 * Set MPU powerdomain's next power state to RETENTION;
 	 * preserve logic state during retention
 	 */
-	pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
-	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
+	pwrdm_set_next_fpwrst(mpu_pwrdm, PWRDM_FUNC_PWRST_CSWR);
 
 	/* Force-power down DSP, GFX powerdomains */
 
 	pwrdm = clkdm_get_pwrdm(dsp_clkdm);
-	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
+	pwrdm_set_next_fpwrst(pwrdm, PWRDM_FUNC_PWRST_OFF);
 	clkdm_sleep(dsp_clkdm);
 
 	pwrdm = clkdm_get_pwrdm(gfx_clkdm);
-	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
+	pwrdm_set_next_fpwrst(pwrdm, PWRDM_FUNC_PWRST_OFF);
 	clkdm_sleep(gfx_clkdm);
 
 	/* Enable hardware-supervised idle for all clkdms */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index e4fc88c..2049b7f 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -111,7 +111,7 @@ static void omap3_core_restore_context(void)
 static void omap3_save_secure_ram_context(void)
 {
 	u32 ret;
-	int mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+	int mpu_next_state = pwrdm_read_next_fpwrst(mpu_pwrdm);
 
 	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
 		/*
@@ -119,10 +119,10 @@ static void omap3_save_secure_ram_context(void)
 		 * otherwise the WFI executed inside the ROM code
 		 * will hang the system.
 		 */
-		pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
+		pwrdm_set_next_fpwrst(mpu_pwrdm, PWRDM_FUNC_PWRST_ON);
 		ret = _omap_save_secure_sram((u32 *)
 				__pa(omap3_secure_ram_storage));
-		pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state);
+		pwrdm_set_next_fpwrst(mpu_pwrdm, mpu_next_state);
 		/* Following is for error tracking, it should not happen */
 		if (ret) {
 			pr_err("save_secure_sram() returns %08x\n", ret);
@@ -241,21 +241,23 @@ void omap_sram_idle(void)
 	/* save_state = 2 => Only L2 lost */
 	/* save_state = 3 => L1, L2 and logic lost */
 	int save_state = 0;
-	int mpu_next_state = PWRDM_POWER_ON;
-	int per_next_state = PWRDM_POWER_ON;
-	int core_next_state = PWRDM_POWER_ON;
+	int mpu_next_state = PWRDM_FUNC_PWRST_ON;
+	int per_next_state = PWRDM_FUNC_PWRST_ON;
+	int core_next_state = PWRDM_FUNC_PWRST_ON;
 	int per_going_off;
 	int core_prev_state;
 	u32 sdrc_pwr = 0;
 
-	mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+	mpu_next_state = pwrdm_read_next_fpwrst(mpu_pwrdm);
 	switch (mpu_next_state) {
-	case PWRDM_POWER_ON:
-	case PWRDM_POWER_RET:
+	case PWRDM_FUNC_PWRST_ON:
+	case PWRDM_FUNC_PWRST_INACTIVE:
+	case PWRDM_FUNC_PWRST_CSWR:
 		/* No need to save context */
 		save_state = 0;
 		break;
-	case PWRDM_POWER_OFF:
+	case PWRDM_FUNC_PWRST_OSWR:
+	case PWRDM_FUNC_PWRST_OFF:
 		save_state = 3;
 		break;
 	default:
@@ -265,29 +267,30 @@ void omap_sram_idle(void)
 	}
 
 	/* NEON control */
-	if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
-		pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state);
+	if (pwrdm_read_fpwrst(neon_pwrdm) == PWRDM_FUNC_PWRST_ON)
+		pwrdm_set_next_fpwrst(neon_pwrdm, mpu_next_state);
 
 	/* Enable IO-PAD and IO-CHAIN wakeups */
-	per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
-	core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
+	per_next_state = pwrdm_read_next_fpwrst(per_pwrdm);
+	core_next_state = pwrdm_read_next_fpwrst(core_pwrdm);
 
-	if (mpu_next_state < PWRDM_POWER_ON) {
+	if (mpu_next_state < PWRDM_FUNC_PWRST_ON) {
 		pwrdm_pre_transition(mpu_pwrdm);
 		pwrdm_pre_transition(neon_pwrdm);
 	}
 
 	/* PER */
-	if (per_next_state < PWRDM_POWER_ON) {
+	if (per_next_state < PWRDM_FUNC_PWRST_ON) {
 		pwrdm_pre_transition(per_pwrdm);
-		per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
+		per_going_off = (per_next_state == PWRDM_FUNC_PWRST_OFF) ?
+				1 : 0;
 		omap2_gpio_prepare_for_idle(per_going_off);
 	}
 
 	/* CORE */
-	if (core_next_state < PWRDM_POWER_ON) {
+	if (core_next_state < PWRDM_FUNC_PWRST_ON) {
 		pwrdm_pre_transition(core_pwrdm);
-		if (core_next_state == PWRDM_POWER_OFF) {
+		if (core_next_state == PWRDM_FUNC_PWRST_OFF) {
 			omap3_core_save_context();
 			omap3_cm_save_context();
 		}
@@ -304,7 +307,7 @@ void omap_sram_idle(void)
 	if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
 	    (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
 	     omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
-	    core_next_state == PWRDM_POWER_OFF)
+	    core_next_state == PWRDM_FUNC_PWRST_OFF)
 		sdrc_pwr = sdrc_read_reg(SDRC_POWER);
 
 	/*
@@ -323,19 +326,19 @@ void omap_sram_idle(void)
 	if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
 	    (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
 	     omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
-	    core_next_state == PWRDM_POWER_OFF)
+	    core_next_state == PWRDM_FUNC_PWRST_OFF)
 		sdrc_write_reg(sdrc_pwr, SDRC_POWER);
 
 	/* CORE */
-	if (core_next_state < PWRDM_POWER_ON) {
-		core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
-		if (core_prev_state == PWRDM_POWER_OFF) {
+	if (core_next_state < PWRDM_FUNC_PWRST_ON) {
+		core_prev_state = pwrdm_read_prev_fpwrst(core_pwrdm);
+		if (core_prev_state == PWRDM_FUNC_PWRST_OFF) {
 			omap3_core_restore_context();
 			omap3_cm_restore_context();
 			omap3_sram_restore_context();
 			omap2_sms_restore_context();
 		}
-		if (core_next_state == PWRDM_POWER_OFF)
+		if (core_next_state == PWRDM_FUNC_PWRST_OFF)
 			omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
 					       OMAP3430_GR_MOD,
 					       OMAP3_PRM_VOLTCTRL_OFFSET);
@@ -344,12 +347,12 @@ void omap_sram_idle(void)
 	omap3_intc_resume_idle();
 
 	/* PER */
-	if (per_next_state < PWRDM_POWER_ON) {
+	if (per_next_state < PWRDM_FUNC_PWRST_ON) {
 		omap2_gpio_resume_after_idle();
 		pwrdm_post_transition(per_pwrdm);
 	}
 
-	if (mpu_next_state < PWRDM_POWER_ON) {
+	if (mpu_next_state < PWRDM_FUNC_PWRST_ON) {
 		pwrdm_post_transition(mpu_pwrdm);
 		pwrdm_post_transition(neon_pwrdm);
 	}
@@ -382,10 +385,10 @@ static int omap3_pm_suspend(void)
 
 	/* Read current next_pwrsts */
 	list_for_each_entry(pwrst, &pwrst_list, node)
-		pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
+		pwrst->saved_state = pwrdm_read_next_fpwrst(pwrst->pwrdm);
 	/* Set ones wanted by suspend */
 	list_for_each_entry(pwrst, &pwrst_list, node) {
-		if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
+		if (pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state))
 			goto restore;
 		if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
 			goto restore;
@@ -398,14 +401,14 @@ static int omap3_pm_suspend(void)
 restore:
 	/* Restore next_pwrsts */
 	list_for_each_entry(pwrst, &pwrst_list, node) {
-		state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
+		state = pwrdm_read_prev_fpwrst(pwrst->pwrdm);
 		if (state > pwrst->next_state) {
 			pr_info("Powerdomain (%s) didn't enter "
 				"target state %d\n",
 			       pwrst->pwrdm->name, pwrst->next_state);
 			ret = -1;
 		}
-		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
+		pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->saved_state);
 	}
 	if (ret)
 		pr_err("Could not enter target state in pm_suspend\n");
@@ -577,21 +580,21 @@ void omap3_pm_off_mode_enable(int enable)
 	u32 state;
 
 	if (enable)
-		state = PWRDM_POWER_OFF;
+		state = PWRDM_FUNC_PWRST_OFF;
 	else
-		state = PWRDM_POWER_RET;
+		state = PWRDM_FUNC_PWRST_CSWR;
 
 	list_for_each_entry(pwrst, &pwrst_list, node) {
 		if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
 				pwrst->pwrdm == core_pwrdm &&
-				state == PWRDM_POWER_OFF) {
-			pwrst->next_state = PWRDM_POWER_RET;
+				state == PWRDM_FUNC_PWRST_OFF) {
+			pwrst->next_state = PWRDM_FUNC_PWRST_CSWR;
 			pr_warn("%s: Core OFF disabled due to errata i583\n",
 				__func__);
 		} else {
 			pwrst->next_state = state;
 		}
-		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+		pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state);
 	}
 }
 
@@ -630,13 +633,13 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+	pwrst->next_state = PWRDM_FUNC_PWRST_CSWR;
 	list_add(&pwrst->node, &pwrst_list);
 
 	if (pwrdm_has_hdwr_sar(pwrdm))
 		pwrdm_enable_hdwr_sar(pwrdm);
 
-	return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+	return pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state);
 }
 
 /*
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index ea24174..3d31880 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -28,7 +28,6 @@ struct power_state {
 	u32 next_state;
 #ifdef CONFIG_SUSPEND
 	u32 saved_state;
-	u32 saved_logic_state;
 #endif
 	struct list_head node;
 };
@@ -43,16 +42,12 @@ static int omap4_pm_suspend(void)
 	u32 cpu_id = smp_processor_id();
 
 	/* Save current powerdomain state */
-	list_for_each_entry(pwrst, &pwrst_list, node) {
-		pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
-		pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm);
-	}
+	list_for_each_entry(pwrst, &pwrst_list, node)
+		pwrst->saved_state = pwrdm_read_next_fpwrst(pwrst->pwrdm);
 
 	/* Set targeted power domain states by suspend */
-	list_for_each_entry(pwrst, &pwrst_list, node) {
-		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
-		pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF);
-	}
+	list_for_each_entry(pwrst, &pwrst_list, node)
+		pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state);
 
 	/*
 	 * For MPUSS to hit power domain retention(CSWR or OSWR),
@@ -63,19 +58,18 @@ static int omap4_pm_suspend(void)
 	 * domain CSWR is not supported by hardware.
 	 * More details can be found in OMAP4430 TRM section 4.3.4.2.
 	 */
-	omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF);
+	omap4_enter_lowpower(cpu_id, PWRDM_FUNC_PWRST_OFF);
 
 	/* Restore next powerdomain state */
 	list_for_each_entry(pwrst, &pwrst_list, node) {
-		state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
+		state = pwrdm_read_prev_fpwrst(pwrst->pwrdm);
 		if (state > pwrst->next_state) {
 			pr_info("Powerdomain (%s) didn't enter "
 			       "target state %d\n",
 			       pwrst->pwrdm->name, pwrst->next_state);
 			ret = -1;
 		}
-		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
-		pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state);
+		pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->saved_state);
 	}
 	if (ret)
 		pr_crit("Could not enter target state in pm_suspend\n");
@@ -113,10 +107,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 		return -ENOMEM;
 
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+	pwrst->next_state = PWRDM_FUNC_PWRST_CSWR;
 	list_add(&pwrst->node, &pwrst_list);
 
-	return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+	return pwrdm_set_next_fpwrst(pwrst->pwrdm, pwrst->next_state);
 }
 
 /**
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index a8f7a81..1f9ed2c 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -317,7 +317,7 @@ int pwrdm_complete_init(void)
 		return -EACCES;
 
 	list_for_each_entry(temp_p, &pwrdm_list, node)
-		pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
+		pwrdm_set_next_fpwrst(temp_p, PWRDM_FUNC_PWRST_ON);
 
 	return 0;
 }
-- 
1.7.7.6

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

* [PATCH 5/8] ARM: OMAP2+: PM: use power domain functional state in stats counters
  2012-08-15 10:02 ` Jean Pihet
@ 2012-08-15 10:02   ` Jean Pihet
  -1 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Santosh Shilimkar, Nishanth Menon
  Cc: Jean Pihet

The PM code uses some counters to keep track of the power domains
transitions, in order to provide the information to drivers (in
pwrdm_get_context_loss_count) and to expose the information to
sysfs for debug purpose.

This patch provides the information for each functional state.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/pm-debug.c    |   15 ++++++++-------
 arch/arm/mach-omap2/powerdomain.c |   12 ++++++------
 arch/arm/mach-omap2/powerdomain.h |    4 ++--
 3 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 814bcd9..8eaa3f2 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -53,9 +53,10 @@ enum {
 	DEBUG_FILE_TIMERS,
 };
 
-static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
+static const char pwrdm_state_names[][PWRDM_MAX_FUNC_PWRSTS] = {
 	"OFF",
-	"RET",
+	"OSWR",
+	"CSWR",
 	"INA",
 	"ON"
 };
@@ -102,13 +103,13 @@ static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
 		strncmp(pwrdm->name, "dpll", 4) == 0)
 		return 0;
 
-	if (pwrdm->state != pwrdm_read_pwrst(pwrdm))
+	if (pwrdm->state != pwrdm_read_fpwrst(pwrdm))
 		printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n",
-			pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm));
+		       pwrdm->name, pwrdm->state, pwrdm_read_fpwrst(pwrdm));
 
 	seq_printf(s, "%s (%s)", pwrdm->name,
 			pwrdm_state_names[pwrdm->state]);
-	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
+	for (i = 0; i < PWRDM_MAX_FUNC_PWRSTS; i++)
 		seq_printf(s, ",%s:%d", pwrdm_state_names[i],
 			pwrdm->state_counter[i]);
 
@@ -137,7 +138,7 @@ static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
 	seq_printf(s, "%s (%s)", pwrdm->name,
 		pwrdm_state_names[pwrdm->state]);
 
-	for (i = 0; i < 4; i++)
+	for (i = 0; i < PWRDM_MAX_FUNC_PWRSTS; i++)
 		seq_printf(s, ",%s:%lld", pwrdm_state_names[i],
 			pwrdm->state_timer[i]);
 
@@ -211,7 +212,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir)
 
 	t = sched_clock();
 
-	for (i = 0; i < 4; i++)
+	for (i = 0; i < PWRDM_MAX_FUNC_PWRSTS; i++)
 		pwrdm->state_timer[i] = 0;
 
 	pwrdm->timer = t;
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 1f9ed2c..6b8580b 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -106,7 +106,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 	list_add(&pwrdm->node, &pwrdm_list);
 
 	/* Initialize the powerdomain's state counter */
-	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
+	for (i = 0; i < PWRDM_MAX_FUNC_PWRSTS; i++)
 		pwrdm->state_counter[i] = 0;
 
 	pwrdm->ret_logic_off_counter = 0;
@@ -114,7 +114,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 		pwrdm->ret_mem_off_counter[i] = 0;
 
 	pwrdm_wait_transition(pwrdm);
-	pwrdm->state = pwrdm_read_pwrst(pwrdm);
+	pwrdm->state = pwrdm_read_fpwrst(pwrdm);
 	pwrdm->state_counter[pwrdm->state] = 1;
 
 	pr_debug("powerdomain: registered %s\n", pwrdm->name);
@@ -149,17 +149,17 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 	if (pwrdm == NULL)
 		return -EINVAL;
 
-	state = pwrdm_read_pwrst(pwrdm);
+	state = pwrdm_read_fpwrst(pwrdm);
 
 	switch (flag) {
 	case PWRDM_STATE_NOW:
 		prev = pwrdm->state;
 		break;
 	case PWRDM_STATE_PREV:
-		prev = pwrdm_read_prev_pwrst(pwrdm);
+		prev = pwrdm_read_prev_fpwrst(pwrdm);
 		if (pwrdm->state != prev)
 			pwrdm->state_counter[prev]++;
-		if (prev == PWRDM_POWER_RET)
+		if (prev == PWRDM_FUNC_PWRST_OSWR)
 			_update_logic_membank_counters(pwrdm);
 		/*
 		 * If the power domain did not hit the desired state,
@@ -1367,7 +1367,7 @@ int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
 		return -ENODEV;
 	}
 
-	count = pwrdm->state_counter[PWRDM_POWER_OFF];
+	count = pwrdm->state_counter[PWRDM_FUNC_PWRST_OFF];
 	count += pwrdm->ret_logic_off_counter;
 
 	for (i = 0; i < pwrdm->banks; i++)
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 23b9da9..df83c7c 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -146,7 +146,7 @@ struct powerdomain {
 	struct list_head voltdm_node;
 	spinlock_t lock;
 	int state;
-	unsigned state_counter[PWRDM_MAX_PWRSTS];
+	unsigned state_counter[PWRDM_MAX_FUNC_PWRSTS];
 	unsigned ret_logic_off_counter;
 	unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];
 
@@ -160,7 +160,7 @@ struct powerdomain {
 
 #ifdef CONFIG_PM_DEBUG
 	s64 timer;
-	s64 state_timer[PWRDM_MAX_PWRSTS];
+	s64 state_timer[PWRDM_MAX_FUNC_PWRSTS];
 #endif
 };
 
-- 
1.7.7.6


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

* [PATCH 5/8] ARM: OMAP2+: PM: use power domain functional state in stats counters
@ 2012-08-15 10:02   ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

The PM code uses some counters to keep track of the power domains
transitions, in order to provide the information to drivers (in
pwrdm_get_context_loss_count) and to expose the information to
sysfs for debug purpose.

This patch provides the information for each functional state.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/pm-debug.c    |   15 ++++++++-------
 arch/arm/mach-omap2/powerdomain.c |   12 ++++++------
 arch/arm/mach-omap2/powerdomain.h |    4 ++--
 3 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 814bcd9..8eaa3f2 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -53,9 +53,10 @@ enum {
 	DEBUG_FILE_TIMERS,
 };
 
-static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
+static const char pwrdm_state_names[][PWRDM_MAX_FUNC_PWRSTS] = {
 	"OFF",
-	"RET",
+	"OSWR",
+	"CSWR",
 	"INA",
 	"ON"
 };
@@ -102,13 +103,13 @@ static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
 		strncmp(pwrdm->name, "dpll", 4) == 0)
 		return 0;
 
-	if (pwrdm->state != pwrdm_read_pwrst(pwrdm))
+	if (pwrdm->state != pwrdm_read_fpwrst(pwrdm))
 		printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n",
-			pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm));
+		       pwrdm->name, pwrdm->state, pwrdm_read_fpwrst(pwrdm));
 
 	seq_printf(s, "%s (%s)", pwrdm->name,
 			pwrdm_state_names[pwrdm->state]);
-	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
+	for (i = 0; i < PWRDM_MAX_FUNC_PWRSTS; i++)
 		seq_printf(s, ",%s:%d", pwrdm_state_names[i],
 			pwrdm->state_counter[i]);
 
@@ -137,7 +138,7 @@ static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
 	seq_printf(s, "%s (%s)", pwrdm->name,
 		pwrdm_state_names[pwrdm->state]);
 
-	for (i = 0; i < 4; i++)
+	for (i = 0; i < PWRDM_MAX_FUNC_PWRSTS; i++)
 		seq_printf(s, ",%s:%lld", pwrdm_state_names[i],
 			pwrdm->state_timer[i]);
 
@@ -211,7 +212,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir)
 
 	t = sched_clock();
 
-	for (i = 0; i < 4; i++)
+	for (i = 0; i < PWRDM_MAX_FUNC_PWRSTS; i++)
 		pwrdm->state_timer[i] = 0;
 
 	pwrdm->timer = t;
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 1f9ed2c..6b8580b 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -106,7 +106,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 	list_add(&pwrdm->node, &pwrdm_list);
 
 	/* Initialize the powerdomain's state counter */
-	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
+	for (i = 0; i < PWRDM_MAX_FUNC_PWRSTS; i++)
 		pwrdm->state_counter[i] = 0;
 
 	pwrdm->ret_logic_off_counter = 0;
@@ -114,7 +114,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 		pwrdm->ret_mem_off_counter[i] = 0;
 
 	pwrdm_wait_transition(pwrdm);
-	pwrdm->state = pwrdm_read_pwrst(pwrdm);
+	pwrdm->state = pwrdm_read_fpwrst(pwrdm);
 	pwrdm->state_counter[pwrdm->state] = 1;
 
 	pr_debug("powerdomain: registered %s\n", pwrdm->name);
@@ -149,17 +149,17 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 	if (pwrdm == NULL)
 		return -EINVAL;
 
-	state = pwrdm_read_pwrst(pwrdm);
+	state = pwrdm_read_fpwrst(pwrdm);
 
 	switch (flag) {
 	case PWRDM_STATE_NOW:
 		prev = pwrdm->state;
 		break;
 	case PWRDM_STATE_PREV:
-		prev = pwrdm_read_prev_pwrst(pwrdm);
+		prev = pwrdm_read_prev_fpwrst(pwrdm);
 		if (pwrdm->state != prev)
 			pwrdm->state_counter[prev]++;
-		if (prev == PWRDM_POWER_RET)
+		if (prev == PWRDM_FUNC_PWRST_OSWR)
 			_update_logic_membank_counters(pwrdm);
 		/*
 		 * If the power domain did not hit the desired state,
@@ -1367,7 +1367,7 @@ int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
 		return -ENODEV;
 	}
 
-	count = pwrdm->state_counter[PWRDM_POWER_OFF];
+	count = pwrdm->state_counter[PWRDM_FUNC_PWRST_OFF];
 	count += pwrdm->ret_logic_off_counter;
 
 	for (i = 0; i < pwrdm->banks; i++)
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 23b9da9..df83c7c 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -146,7 +146,7 @@ struct powerdomain {
 	struct list_head voltdm_node;
 	spinlock_t lock;
 	int state;
-	unsigned state_counter[PWRDM_MAX_PWRSTS];
+	unsigned state_counter[PWRDM_MAX_FUNC_PWRSTS];
 	unsigned ret_logic_off_counter;
 	unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];
 
@@ -160,7 +160,7 @@ struct powerdomain {
 
 #ifdef CONFIG_PM_DEBUG
 	s64 timer;
-	s64 state_timer[PWRDM_MAX_PWRSTS];
+	s64 state_timer[PWRDM_MAX_FUNC_PWRSTS];
 #endif
 };
 
-- 
1.7.7.6

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

* [PATCH 6/8] ARM: OMAP2+: PM debug: trace the functional power domains states
  2012-08-15 10:02 ` Jean Pihet
@ 2012-08-15 10:02   ` Jean Pihet
  -1 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Santosh Shilimkar, Nishanth Menon
  Cc: Jean Pihet

Trace the power domain transitions using the functional power states,
which include the power and logic states.

While at it, fix the trace in the case a power domain did not hit
the desired state, as reported by Paul Walmsley.

Reported-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |   15 +++++----------
 1 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 6b8580b..06a566b 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -144,7 +144,7 @@ static void _update_logic_membank_counters(struct powerdomain *pwrdm)
 static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 {
 
-	int prev, state, trace_state = 0;
+	int prev, next, state, trace_state;
 
 	if (pwrdm == NULL)
 		return -EINVAL;
@@ -165,10 +165,10 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 		 * If the power domain did not hit the desired state,
 		 * generate a trace event with both the desired and hit states
 		 */
-		if (state != prev) {
+		next = pwrdm_read_next_fpwrst(pwrdm);
+		if (next != prev) {
 			trace_state = (PWRDM_TRACE_STATES_FLAG |
-				       ((state & OMAP_POWERSTATE_MASK) << 8) |
-				       ((prev & OMAP_POWERSTATE_MASK) << 0));
+				       (next << 8) | (prev << 0));
 			trace_power_domain_target(pwrdm->name, trace_state,
 						  smp_processor_id());
 		}
@@ -781,13 +781,8 @@ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 	pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
 		 pwrdm->name, pwrst);
 
-	if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) {
-		/* Trace the pwrdm desired target state */
-		trace_power_domain_target(pwrdm->name, pwrst,
-					  smp_processor_id());
-		/* Program the pwrdm desired target state */
+	if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst)
 		ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
-	}
 
 	return ret;
 }
-- 
1.7.7.6


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

* [PATCH 6/8] ARM: OMAP2+: PM debug: trace the functional power domains states
@ 2012-08-15 10:02   ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

Trace the power domain transitions using the functional power states,
which include the power and logic states.

While at it, fix the trace in the case a power domain did not hit
the desired state, as reported by Paul Walmsley.

Reported-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |   15 +++++----------
 1 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 6b8580b..06a566b 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -144,7 +144,7 @@ static void _update_logic_membank_counters(struct powerdomain *pwrdm)
 static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 {
 
-	int prev, state, trace_state = 0;
+	int prev, next, state, trace_state;
 
 	if (pwrdm == NULL)
 		return -EINVAL;
@@ -165,10 +165,10 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 		 * If the power domain did not hit the desired state,
 		 * generate a trace event with both the desired and hit states
 		 */
-		if (state != prev) {
+		next = pwrdm_read_next_fpwrst(pwrdm);
+		if (next != prev) {
 			trace_state = (PWRDM_TRACE_STATES_FLAG |
-				       ((state & OMAP_POWERSTATE_MASK) << 8) |
-				       ((prev & OMAP_POWERSTATE_MASK) << 0));
+				       (next << 8) | (prev << 0));
 			trace_power_domain_target(pwrdm->name, trace_state,
 						  smp_processor_id());
 		}
@@ -781,13 +781,8 @@ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 	pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
 		 pwrdm->name, pwrst);
 
-	if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) {
-		/* Trace the pwrdm desired target state */
-		trace_power_domain_target(pwrdm->name, pwrst,
-					  smp_processor_id());
-		/* Program the pwrdm desired target state */
+	if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst)
 		ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
-	}
 
 	return ret;
 }
-- 
1.7.7.6

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

* [PATCH 7/8] ARM: OMAP2+: powerdomain: add error logs
  2012-08-15 10:02 ` Jean Pihet
@ 2012-08-15 10:02   ` Jean Pihet
  -1 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Santosh Shilimkar, Nishanth Menon

From: Nishanth Menon <nm@ti.com>

Silent failure makes debug hard. So, provide rate limited error
messages in functional and oft-used code to prevent spam
when something goes wrong..

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |   72 +++++++++++++++++++++++++++++-------
 1 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 06a566b..691247e 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -19,6 +19,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/ratelimit.h>
 #include <trace/events/power.h>
 
 #include "cm2xxx_3xxx.h"
@@ -146,8 +147,12 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 
 	int prev, next, state, trace_state;
 
-	if (pwrdm == NULL)
+	if (pwrdm == NULL) {
+		WARN_ONCE(1, "null pwrdm\n");
+		pr_err_ratelimited("%s: powerdomain: null pwrdm param\n",
+				   __func__);
 		return -EINVAL;
+	}
 
 	state = pwrdm_read_fpwrst(pwrdm);
 
@@ -174,6 +179,8 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 		}
 		break;
 	default:
+		pr_err_ratelimited("%s: powerdomain %s: bad flag %d\n",
+				   __func__, pwrdm->name, flag);
 		return -EINVAL;
 	}
 
@@ -690,7 +697,8 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 	unsigned long flags;
 
 	if (!pwrdm || IS_ERR(pwrdm)) {
-		pr_debug("%s: invalid params: pwrdm=%p\n", __func__, pwrdm);
+		pr_err_ratelimited("%s: invalid params: pwrdm=%p\n",
+				   __func__, pwrdm);
 		return -EINVAL;
 	}
 
@@ -775,8 +783,11 @@ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (!(pwrdm->pwrsts & (1 << pwrst)))
+	if (!(pwrdm->pwrsts & (1 << pwrst))) {
+		pr_err_ratelimited("%s: powerdomain %s: bad pwrst %d\n",
+				   __func__, pwrdm->name, pwrst);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
 		 pwrdm->name, pwrst);
@@ -924,8 +935,11 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
+	if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst))) {
+		pr_err_ratelimited("%s: powerdomain %s: bad pwrst %d\n",
+				   __func__, pwrdm->name, pwrst);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
 		 pwrdm->name, pwrst);
@@ -958,11 +972,17 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return -EEXIST;
+	}
 
-	if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
+	if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst))) {
+		pr_err_ratelimited("%s: powerdomain %s: bank %d bad pwrst %d\n",
+				   __func__, pwrdm->name, bank, pwrst);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: setting next memory powerstate for domain %s "
 		 "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
@@ -996,11 +1016,17 @@ int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return -EEXIST;
+	}
 
-	if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
+	if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst))) {
+		pr_err_ratelimited("%s: powerdomain %s: bank %d bad pwrst %d\n",
+				   __func__, pwrdm->name, bank, pwrst);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: setting next memory powerstate for domain %s "
 		 "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
@@ -1092,8 +1118,11 @@ int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 	if (!pwrdm)
 		return ret;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return ret;
+	}
 
 	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
 		bank = 1;
@@ -1122,8 +1151,11 @@ int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 	if (!pwrdm)
 		return ret;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return ret;
+	}
 
 	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
 		bank = 1;
@@ -1151,8 +1183,11 @@ int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
 	if (!pwrdm)
 		return ret;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return ret;
+	}
 
 	if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst)
 		ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank);
@@ -1208,8 +1243,11 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
 	if (!pwrdm)
 		return ret;
 
-	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) {
+		pr_err_ratelimited("%s: powerdomain %s: no HDSAR in flag %d\n",
+				   __func__, pwrdm->name, pwrdm->flags);
 		return ret;
+	}
 
 	pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
 		 pwrdm->name);
@@ -1238,8 +1276,11 @@ int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
 	if (!pwrdm)
 		return ret;
 
-	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) {
+		pr_err_ratelimited("%s: powerdomain %s: no HDSAR in flag %d\n",
+				   __func__, pwrdm->name, pwrdm->flags);
 		return ret;
+	}
 
 	pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
 		 pwrdm->name);
@@ -1279,8 +1320,11 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE))
+	if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
+		pr_err_ratelimited("%s: powerdomain %s:no lowpwrch in flag%d\n",
+				   __func__, pwrdm->name, pwrdm->flags);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n",
 		 pwrdm->name);
-- 
1.7.7.6


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

* [PATCH 7/8] ARM: OMAP2+: powerdomain: add error logs
@ 2012-08-15 10:02   ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nishanth Menon <nm@ti.com>

Silent failure makes debug hard. So, provide rate limited error
messages in functional and oft-used code to prevent spam
when something goes wrong..

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |   72 +++++++++++++++++++++++++++++-------
 1 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 06a566b..691247e 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -19,6 +19,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/ratelimit.h>
 #include <trace/events/power.h>
 
 #include "cm2xxx_3xxx.h"
@@ -146,8 +147,12 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 
 	int prev, next, state, trace_state;
 
-	if (pwrdm == NULL)
+	if (pwrdm == NULL) {
+		WARN_ONCE(1, "null pwrdm\n");
+		pr_err_ratelimited("%s: powerdomain: null pwrdm param\n",
+				   __func__);
 		return -EINVAL;
+	}
 
 	state = pwrdm_read_fpwrst(pwrdm);
 
@@ -174,6 +179,8 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 		}
 		break;
 	default:
+		pr_err_ratelimited("%s: powerdomain %s: bad flag %d\n",
+				   __func__, pwrdm->name, flag);
 		return -EINVAL;
 	}
 
@@ -690,7 +697,8 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
 	unsigned long flags;
 
 	if (!pwrdm || IS_ERR(pwrdm)) {
-		pr_debug("%s: invalid params: pwrdm=%p\n", __func__, pwrdm);
+		pr_err_ratelimited("%s: invalid params: pwrdm=%p\n",
+				   __func__, pwrdm);
 		return -EINVAL;
 	}
 
@@ -775,8 +783,11 @@ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (!(pwrdm->pwrsts & (1 << pwrst)))
+	if (!(pwrdm->pwrsts & (1 << pwrst))) {
+		pr_err_ratelimited("%s: powerdomain %s: bad pwrst %d\n",
+				   __func__, pwrdm->name, pwrst);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
 		 pwrdm->name, pwrst);
@@ -924,8 +935,11 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
+	if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst))) {
+		pr_err_ratelimited("%s: powerdomain %s: bad pwrst %d\n",
+				   __func__, pwrdm->name, pwrst);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
 		 pwrdm->name, pwrst);
@@ -958,11 +972,17 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return -EEXIST;
+	}
 
-	if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
+	if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst))) {
+		pr_err_ratelimited("%s: powerdomain %s: bank %d bad pwrst %d\n",
+				   __func__, pwrdm->name, bank, pwrst);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: setting next memory powerstate for domain %s "
 		 "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
@@ -996,11 +1016,17 @@ int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return -EEXIST;
+	}
 
-	if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
+	if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst))) {
+		pr_err_ratelimited("%s: powerdomain %s: bank %d bad pwrst %d\n",
+				   __func__, pwrdm->name, bank, pwrst);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: setting next memory powerstate for domain %s "
 		 "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
@@ -1092,8 +1118,11 @@ int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 	if (!pwrdm)
 		return ret;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return ret;
+	}
 
 	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
 		bank = 1;
@@ -1122,8 +1151,11 @@ int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 	if (!pwrdm)
 		return ret;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return ret;
+	}
 
 	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
 		bank = 1;
@@ -1151,8 +1183,11 @@ int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
 	if (!pwrdm)
 		return ret;
 
-	if (pwrdm->banks < (bank + 1))
+	if (pwrdm->banks < (bank + 1)) {
+		pr_err_ratelimited("%s: powerdomain %s: bad bank %d\n",
+				   __func__, pwrdm->name, bank);
 		return ret;
+	}
 
 	if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst)
 		ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank);
@@ -1208,8 +1243,11 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
 	if (!pwrdm)
 		return ret;
 
-	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) {
+		pr_err_ratelimited("%s: powerdomain %s: no HDSAR in flag %d\n",
+				   __func__, pwrdm->name, pwrdm->flags);
 		return ret;
+	}
 
 	pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
 		 pwrdm->name);
@@ -1238,8 +1276,11 @@ int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
 	if (!pwrdm)
 		return ret;
 
-	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) {
+		pr_err_ratelimited("%s: powerdomain %s: no HDSAR in flag %d\n",
+				   __func__, pwrdm->name, pwrdm->flags);
 		return ret;
+	}
 
 	pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
 		 pwrdm->name);
@@ -1279,8 +1320,11 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE))
+	if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
+		pr_err_ratelimited("%s: powerdomain %s:no lowpwrch in flag%d\n",
+				   __func__, pwrdm->name, pwrdm->flags);
 		return -EINVAL;
+	}
 
 	pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n",
 		 pwrdm->name);
-- 
1.7.7.6

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

* [PATCH 8/8] ARM: OMAP2+: PM: reorganize the powerdomain API in public and private parts
  2012-08-15 10:02 ` Jean Pihet
@ 2012-08-15 10:02   ` Jean Pihet
  -1 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Santosh Shilimkar, Nishanth Menon
  Cc: Jean Pihet

The newly added code for functional power states re-defines the
API to query and control the power domains settings.

The API is now split in the following parts in powerdomain.h:
- the public or external API, to be used by external PM components:
  cpuidle, suspend, pmxxxx, clock* etc.
- the private or internal API, to be used by the low level PM code
  only: powerdomain*, pm-debug, hwmod, voltage, clockdomainxxxx.

No functional change is introduced by this patch.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomain.h |  119 ++++++++++++++++++++-----------------
 1 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index df83c7c..0bf613c 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -24,6 +24,11 @@
 
 #include "voltage.h"
 
+/***************************************************************
+ * External API, to be used by external PM components: cpuidle,
+ * suspend, pmxxxx, clock* etc.
+ ***************************************************************/
+
 /* Powerdomain functional power states, used by the external API functions */
 enum pwrdm_func_state {
 	PWRDM_FUNC_PWRST_OFF		= 0x0,
@@ -44,6 +49,62 @@ enum pwrdm_logic_mem_state {
 	PWRDM_MAX_LOGIC_MEM_PWRST	/* Last value, used as the max value */
 };
 
+struct clockdomain;
+struct powerdomain;
+
+struct powerdomain *pwrdm_lookup(const char *name);
+
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+			void *user);
+int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
+			void *user);
+
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+			 int (*fn)(struct powerdomain *pwrdm,
+				   struct clockdomain *clkdm));
+struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
+
+int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
+
+/* Functions that query and control the power domain state setings */
+int pwrdm_get_achievable_fpwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
+			  enum pwrdm_func_state fpwrst);
+int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_read_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
+int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
+
+int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
+bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
+
+int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
+int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
+bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
+
+int pwrdm_pre_transition(struct powerdomain *pwrdm);
+int pwrdm_post_transition(struct powerdomain *pwrdm);
+int pwrdm_state_switch(struct powerdomain *pwrdm);
+
+extern void omap242x_powerdomains_init(void);
+extern void omap243x_powerdomains_init(void);
+extern void omap3xxx_powerdomains_init(void);
+extern void am33xx_powerdomains_init(void);
+extern void omap44xx_powerdomains_init(void);
+
+
+/***************************************************************
+ * Internal API, to be included by the low level PM code only:
+ * powerdomain*, pm-debug, hwmod, voltage, clockdomainxxxx
+ ***************************************************************/
+
 /* Powerdomain basic power states */
 #define PWRDM_POWER_OFF		0x0
 #define PWRDM_POWER_RET		0x1
@@ -92,9 +153,6 @@ enum pwrdm_logic_mem_state {
 /* XXX A completely arbitrary number. What is reasonable here? */
 #define PWRDM_TRANSITION_BAILOUT 100000
 
-struct clockdomain;
-struct powerdomain;
-
 /**
  * struct powerdomain - OMAP powerdomain
  * @name: Powerdomain name
@@ -221,67 +279,17 @@ int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs);
 int pwrdm_register_pwrdms(struct powerdomain **pwrdm_list);
 int pwrdm_complete_init(void);
 
-struct powerdomain *pwrdm_lookup(const char *name);
-
-int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
-			void *user);
-int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
-			void *user);
-
-int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
-			 int (*fn)(struct powerdomain *pwrdm,
-				   struct clockdomain *clkdm));
-struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
-
-int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
-
-int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
-			  enum pwrdm_func_state fpwrst);
-int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm);
-int pwrdm_read_fpwrst(struct powerdomain *pwrdm);
-int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm);
-int pwrdm_get_achievable_fpwrst(struct powerdomain *pwrdm, u8 fpwrst);
-int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
-int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
-int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic);
-
 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
-int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
-
 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
-int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
-int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
-
 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_logic_retst(struct powerdomain *pwrdm);
-int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
-int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
-int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
-
-int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
-int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
-bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
 
 int pwrdm_wait_transition(struct powerdomain *pwrdm);
-
-int pwrdm_state_switch(struct powerdomain *pwrdm);
-int pwrdm_pre_transition(struct powerdomain *pwrdm);
-int pwrdm_post_transition(struct powerdomain *pwrdm);
 int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
-int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
-bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
-
-extern void omap242x_powerdomains_init(void);
-extern void omap243x_powerdomains_init(void);
-extern void omap3xxx_powerdomains_init(void);
-extern void am33xx_powerdomains_init(void);
-extern void omap44xx_powerdomains_init(void);
 
 extern struct pwrdm_ops omap2_pwrdm_operations;
 extern struct pwrdm_ops omap3_pwrdm_operations;
@@ -293,8 +301,11 @@ extern u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank);
 extern u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank);
 extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank);
 
+int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic);
+
 extern struct powerdomain wkup_omap2_pwrdm;
 extern struct powerdomain gfx_omap2_pwrdm;
 
-
 #endif
-- 
1.7.7.6


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

* [PATCH 8/8] ARM: OMAP2+: PM: reorganize the powerdomain API in public and private parts
@ 2012-08-15 10:02   ` Jean Pihet
  0 siblings, 0 replies; 28+ messages in thread
From: Jean Pihet @ 2012-08-15 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

The newly added code for functional power states re-defines the
API to query and control the power domains settings.

The API is now split in the following parts in powerdomain.h:
- the public or external API, to be used by external PM components:
  cpuidle, suspend, pmxxxx, clock* etc.
- the private or internal API, to be used by the low level PM code
  only: powerdomain*, pm-debug, hwmod, voltage, clockdomainxxxx.

No functional change is introduced by this patch.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomain.h |  119 ++++++++++++++++++++-----------------
 1 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index df83c7c..0bf613c 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -24,6 +24,11 @@
 
 #include "voltage.h"
 
+/***************************************************************
+ * External API, to be used by external PM components: cpuidle,
+ * suspend, pmxxxx, clock* etc.
+ ***************************************************************/
+
 /* Powerdomain functional power states, used by the external API functions */
 enum pwrdm_func_state {
 	PWRDM_FUNC_PWRST_OFF		= 0x0,
@@ -44,6 +49,62 @@ enum pwrdm_logic_mem_state {
 	PWRDM_MAX_LOGIC_MEM_PWRST	/* Last value, used as the max value */
 };
 
+struct clockdomain;
+struct powerdomain;
+
+struct powerdomain *pwrdm_lookup(const char *name);
+
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+			void *user);
+int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
+			void *user);
+
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+			 int (*fn)(struct powerdomain *pwrdm,
+				   struct clockdomain *clkdm));
+struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
+
+int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
+
+/* Functions that query and control the power domain state setings */
+int pwrdm_get_achievable_fpwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
+			  enum pwrdm_func_state fpwrst);
+int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_read_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm);
+int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
+int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
+
+int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
+bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
+
+int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
+int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
+bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
+
+int pwrdm_pre_transition(struct powerdomain *pwrdm);
+int pwrdm_post_transition(struct powerdomain *pwrdm);
+int pwrdm_state_switch(struct powerdomain *pwrdm);
+
+extern void omap242x_powerdomains_init(void);
+extern void omap243x_powerdomains_init(void);
+extern void omap3xxx_powerdomains_init(void);
+extern void am33xx_powerdomains_init(void);
+extern void omap44xx_powerdomains_init(void);
+
+
+/***************************************************************
+ * Internal API, to be included by the low level PM code only:
+ * powerdomain*, pm-debug, hwmod, voltage, clockdomainxxxx
+ ***************************************************************/
+
 /* Powerdomain basic power states */
 #define PWRDM_POWER_OFF		0x0
 #define PWRDM_POWER_RET		0x1
@@ -92,9 +153,6 @@ enum pwrdm_logic_mem_state {
 /* XXX A completely arbitrary number. What is reasonable here? */
 #define PWRDM_TRANSITION_BAILOUT 100000
 
-struct clockdomain;
-struct powerdomain;
-
 /**
  * struct powerdomain - OMAP powerdomain
  * @name: Powerdomain name
@@ -221,67 +279,17 @@ int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs);
 int pwrdm_register_pwrdms(struct powerdomain **pwrdm_list);
 int pwrdm_complete_init(void);
 
-struct powerdomain *pwrdm_lookup(const char *name);
-
-int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
-			void *user);
-int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
-			void *user);
-
-int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
-			 int (*fn)(struct powerdomain *pwrdm,
-				   struct clockdomain *clkdm));
-struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
-
-int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
-
-int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm,
-			  enum pwrdm_func_state fpwrst);
-int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm);
-int pwrdm_read_fpwrst(struct powerdomain *pwrdm);
-int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm);
-int pwrdm_get_achievable_fpwrst(struct powerdomain *pwrdm, u8 fpwrst);
-int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
-int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
-int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic);
-
 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
-int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
-
 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
-int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
-int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
-
 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_logic_retst(struct powerdomain *pwrdm);
-int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
-int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
-int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
-
-int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
-int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
-bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
 
 int pwrdm_wait_transition(struct powerdomain *pwrdm);
-
-int pwrdm_state_switch(struct powerdomain *pwrdm);
-int pwrdm_pre_transition(struct powerdomain *pwrdm);
-int pwrdm_post_transition(struct powerdomain *pwrdm);
 int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
-int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
-bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
-
-extern void omap242x_powerdomains_init(void);
-extern void omap243x_powerdomains_init(void);
-extern void omap3xxx_powerdomains_init(void);
-extern void am33xx_powerdomains_init(void);
-extern void omap44xx_powerdomains_init(void);
 
 extern struct pwrdm_ops omap2_pwrdm_operations;
 extern struct pwrdm_ops omap3_pwrdm_operations;
@@ -293,8 +301,11 @@ extern u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank);
 extern u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank);
 extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank);
 
+int omap2_pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int omap2_pwrdm_fpwrst_to_logic_pwrst(struct powerdomain *pwrdm, u8 fpwrst);
+int omap2_pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic);
+
 extern struct powerdomain wkup_omap2_pwrdm;
 extern struct powerdomain gfx_omap2_pwrdm;
 
-
 #endif
-- 
1.7.7.6

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

* Re: [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
  2012-08-15 10:02 ` Jean Pihet
@ 2012-08-15 17:05   ` Shilimkar, Santosh
  -1 siblings, 0 replies; 28+ messages in thread
From: Shilimkar, Santosh @ 2012-08-15 17:05 UTC (permalink / raw)
  To: Jean Pihet
  Cc: linux-omap, paul, linux-arm-kernel, khilman, Rajendra Nayak,
	Nishanth Menon, Jean Pihet

Jean,

On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com> wrote:
>
> Here is a re-spin after some comments and suggestions after review.
>
> Implement the functional states for the power domains:
> - unify the API to use the functional states. pwrdm_set_next_fpwrst
>   now is the function to control the power domains power and logic
>   states,
> - reorganize the powerdomain API in internal and external parts,
>   in powerdomain.h [1]
> - protect the power domain state change by a lock in
>   pwrdm_set_next_fpwrst,
> - introduce the functional states for power domains power states and
>   logic power states, and the conversion functions between the
>   functional and internal states,
> - program the logic power state of power domains from the functional
>   states, in pwrdm_set_next_fpwrst
> - convert the OMAP2/3/4 PM code to use the updated API,
> - provide the power domains statistics by functional states,
> - provide ftrace tracepoints with the functional state,
> - provide error logs in critical code, which makes the development
>   easier.
>
> Note: [1] the physical split of internal and external APIs into
>       different header files is not part of this series, it comes as
>       a separate patch set.
>
>
> Based on mainline kernel 3.6.0-rc1.
>
> Tested on OMAP3 Beagleboard, with suspend and cpuidle in RET and
> OFF modes.
>
I didn't find any mention here about why are we going in this path and not
in the direction proposed in another RFC [1]
I have already given my comments[2] against the introduction of another PD
layer which can be avoided easily as demonstrated by the RFC[1]. The comments
are still applicable for this series too.

We really need to reduce OMAP specific framework overhead and
move towards more generic PM frameworks. For me, this series is
a step back-ward from that direction. Am really sorry for being critical
again but I remain unconvinced about this series and the problem it
is trying to solve.

May be you have valid reasons not to follow the approach in [1] and in
that case, it will be good to clarify that so that some of us get
to know your rationale.

Regards
Santosh
[1] http://www.mail-archive.com/linux-omap@vger.kernel.org/msg71732.html
[2] http://www.mail-archive.com/linux-omap@vger.kernel.org/msg69081.html

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

* [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
@ 2012-08-15 17:05   ` Shilimkar, Santosh
  0 siblings, 0 replies; 28+ messages in thread
From: Shilimkar, Santosh @ 2012-08-15 17:05 UTC (permalink / raw)
  To: linux-arm-kernel

Jean,

On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com> wrote:
>
> Here is a re-spin after some comments and suggestions after review.
>
> Implement the functional states for the power domains:
> - unify the API to use the functional states. pwrdm_set_next_fpwrst
>   now is the function to control the power domains power and logic
>   states,
> - reorganize the powerdomain API in internal and external parts,
>   in powerdomain.h [1]
> - protect the power domain state change by a lock in
>   pwrdm_set_next_fpwrst,
> - introduce the functional states for power domains power states and
>   logic power states, and the conversion functions between the
>   functional and internal states,
> - program the logic power state of power domains from the functional
>   states, in pwrdm_set_next_fpwrst
> - convert the OMAP2/3/4 PM code to use the updated API,
> - provide the power domains statistics by functional states,
> - provide ftrace tracepoints with the functional state,
> - provide error logs in critical code, which makes the development
>   easier.
>
> Note: [1] the physical split of internal and external APIs into
>       different header files is not part of this series, it comes as
>       a separate patch set.
>
>
> Based on mainline kernel 3.6.0-rc1.
>
> Tested on OMAP3 Beagleboard, with suspend and cpuidle in RET and
> OFF modes.
>
I didn't find any mention here about why are we going in this path and not
in the direction proposed in another RFC [1]
I have already given my comments[2] against the introduction of another PD
layer which can be avoided easily as demonstrated by the RFC[1]. The comments
are still applicable for this series too.

We really need to reduce OMAP specific framework overhead and
move towards more generic PM frameworks. For me, this series is
a step back-ward from that direction. Am really sorry for being critical
again but I remain unconvinced about this series and the problem it
is trying to solve.

May be you have valid reasons not to follow the approach in [1] and in
that case, it will be good to clarify that so that some of us get
to know your rationale.

Regards
Santosh
[1] http://www.mail-archive.com/linux-omap at vger.kernel.org/msg71732.html
[2] http://www.mail-archive.com/linux-omap at vger.kernel.org/msg69081.html

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

* Re: [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
  2012-08-15 17:05   ` Shilimkar, Santosh
@ 2012-08-16  0:48     ` Paul Walmsley
  -1 siblings, 0 replies; 28+ messages in thread
From: Paul Walmsley @ 2012-08-16  0:48 UTC (permalink / raw)
  To: Shilimkar, Santosh, Jean Pihet
  Cc: Jean Pihet, linux-omap, linux-arm-kernel, khilman,
	Rajendra Nayak, Nishanth Menon

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1448 bytes --]

Hi Santosh,

On Wed, 15 Aug 2012, Shilimkar, Santosh wrote:

> On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com> wrote:
>
> I didn't find any mention here about why are we going in this path and not
> in the direction proposed in another RFC [1]
> I have already given my comments[2] against the introduction of another PD
> layer which can be avoided easily as demonstrated by the RFC[1]. The comments
> are still applicable for this series too.
> 
> We really need to reduce OMAP specific framework overhead and
> move towards more generic PM frameworks. For me, this series is
> a step back-ward from that direction. Am really sorry for being critical
> again but I remain unconvinced about this series and the problem it
> is trying to solve.
> 
> May be you have valid reasons not to follow the approach in [1] and in
> that case, it will be good to clarify that so that some of us get
> to know your rationale.

I've asked Jean to handle the work of evaluating and/or integrating any 
feedback from you and Rajendra into this series.  Jean, has this latest 
series fully considered those issues?  Or are there still some areas of 
misalignment / lack of clarity?

Anyway.  If there's a problem with this process, it sounds like you, 
Rajendra, Jean, Benoît and I should schedule some time to talk over the 
same issues that you discussed with me on the phone.  Perhaps next week?


- Paul

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

* [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
@ 2012-08-16  0:48     ` Paul Walmsley
  0 siblings, 0 replies; 28+ messages in thread
From: Paul Walmsley @ 2012-08-16  0:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Santosh,

On Wed, 15 Aug 2012, Shilimkar, Santosh wrote:

> On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com> wrote:
>
> I didn't find any mention here about why are we going in this path and not
> in the direction proposed in another RFC [1]
> I have already given my comments[2] against the introduction of another PD
> layer which can be avoided easily as demonstrated by the RFC[1]. The comments
> are still applicable for this series too.
> 
> We really need to reduce OMAP specific framework overhead and
> move towards more generic PM frameworks. For me, this series is
> a step back-ward from that direction. Am really sorry for being critical
> again but I remain unconvinced about this series and the problem it
> is trying to solve.
> 
> May be you have valid reasons not to follow the approach in [1] and in
> that case, it will be good to clarify that so that some of us get
> to know your rationale.

I've asked Jean to handle the work of evaluating and/or integrating any 
feedback from you and Rajendra into this series.  Jean, has this latest 
series fully considered those issues?  Or are there still some areas of 
misalignment / lack of clarity?

Anyway.  If there's a problem with this process, it sounds like you, 
Rajendra, Jean, Beno?t and I should schedule some time to talk over the 
same issues that you discussed with me on the phone.  Perhaps next week?


- Paul

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

* Re: [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
  2012-08-16  0:48     ` Paul Walmsley
@ 2012-08-16  5:50       ` Shilimkar, Santosh
  -1 siblings, 0 replies; 28+ messages in thread
From: Shilimkar, Santosh @ 2012-08-16  5:50 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Jean Pihet, Jean Pihet, linux-omap, linux-arm-kernel, khilman,
	Rajendra Nayak, Nishanth Menon

Paul,

On Thu, Aug 16, 2012 at 6:18 AM, Paul Walmsley <paul@pwsan.com> wrote:
>
> Hi Santosh,
>
> On Wed, 15 Aug 2012, Shilimkar, Santosh wrote:
>
> > On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com>
> > wrote:
> >
> > I didn't find any mention here about why are we going in this path and
> > not
> > in the direction proposed in another RFC [1]
> > I have already given my comments[2] against the introduction of another
> > PD
> > layer which can be avoided easily as demonstrated by the RFC[1]. The
> > comments
> > are still applicable for this series too.
> >
> > We really need to reduce OMAP specific framework overhead and
> > move towards more generic PM frameworks. For me, this series is
> > a step back-ward from that direction. Am really sorry for being critical
> > again but I remain unconvinced about this series and the problem it
> > is trying to solve.
> >
> > May be you have valid reasons not to follow the approach in [1] and in
> > that case, it will be good to clarify that so that some of us get
> > to know your rationale.
>
> I've asked Jean to handle the work of evaluating and/or integrating any
> feedback from you and Rajendra into this series.  Jean, has this latest
> series fully considered those issues?  Or are there still some areas of
> misalignment / lack of clarity?
>
Thanks for the information. The main objection to this series was to
not add un-necessary glue layer which still remains.

From our discussion in past on and off list, your main intention for such
a series was -

1. Need a way to support OSWR.
- OSWR by definition is a RET with configurable logic and memory states.
Its a true power state from PD point of view and its not a logical state.
Now since we have agreed to make the OSWR as a static definition
(in all products so far OSWR is used as a static definition with logic
lost, memory retained kind of configuration.)

- The above requirement can be easily fixed by adding the OSWR
as an additional basic power state as demonstrated in RFC.

- There is no need to add another glue layer for above.

2. Locking so that the low level APIs don't race and henec abstracting the
exported API to 1 or 2 and making rest as private functions.

-- Even before this series, except low level PM code, only one
common API was used to set the PD low power state.
int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)

-- Once we make OSWR as basic power state, we also avoid usage of
pwrdm_set_logic_retst() API.

-- We implement lock at this API and export only above API +
may be omap_get_pwrdm_state() kind of API based on need.

-- This solves the second requirement too.

Even if we have more requirement, they can be addressed
too without need of another layer.

If you look at the diffstat alone between two approaches, it is
evident how small piece of code is needed to support above.
Am not too much into the lines of code but basic objection we
have is not to add another glue layer.

Thinking bit loud, for the logical layer for power domain
we should move towards common device power domain
APIs and if needed add/enhance them to support OMAP.
   drivers/base/power/domain.c
May be this though is bit premature but the intetion is
to move towards generic linux framework.

> Anyway.  If there's a problem with this process, it sounds like you,
> Rajendra, Jean, Benoît and I should schedule some time to talk over the
> same issues that you discussed with me on the phone.  Perhaps next week?
>
We can surely do a call if needed. But the comments given so far and the
RFC makes things more or less clear the contention point against the
$subject series.

Regards
Santosh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
@ 2012-08-16  5:50       ` Shilimkar, Santosh
  0 siblings, 0 replies; 28+ messages in thread
From: Shilimkar, Santosh @ 2012-08-16  5:50 UTC (permalink / raw)
  To: linux-arm-kernel

Paul,

On Thu, Aug 16, 2012 at 6:18 AM, Paul Walmsley <paul@pwsan.com> wrote:
>
> Hi Santosh,
>
> On Wed, 15 Aug 2012, Shilimkar, Santosh wrote:
>
> > On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com>
> > wrote:
> >
> > I didn't find any mention here about why are we going in this path and
> > not
> > in the direction proposed in another RFC [1]
> > I have already given my comments[2] against the introduction of another
> > PD
> > layer which can be avoided easily as demonstrated by the RFC[1]. The
> > comments
> > are still applicable for this series too.
> >
> > We really need to reduce OMAP specific framework overhead and
> > move towards more generic PM frameworks. For me, this series is
> > a step back-ward from that direction. Am really sorry for being critical
> > again but I remain unconvinced about this series and the problem it
> > is trying to solve.
> >
> > May be you have valid reasons not to follow the approach in [1] and in
> > that case, it will be good to clarify that so that some of us get
> > to know your rationale.
>
> I've asked Jean to handle the work of evaluating and/or integrating any
> feedback from you and Rajendra into this series.  Jean, has this latest
> series fully considered those issues?  Or are there still some areas of
> misalignment / lack of clarity?
>
Thanks for the information. The main objection to this series was to
not add un-necessary glue layer which still remains.

>From our discussion in past on and off list, your main intention for such
a series was -

1. Need a way to support OSWR.
- OSWR by definition is a RET with configurable logic and memory states.
Its a true power state from PD point of view and its not a logical state.
Now since we have agreed to make the OSWR as a static definition
(in all products so far OSWR is used as a static definition with logic
lost, memory retained kind of configuration.)

- The above requirement can be easily fixed by adding the OSWR
as an additional basic power state as demonstrated in RFC.

- There is no need to add another glue layer for above.

2. Locking so that the low level APIs don't race and henec abstracting the
exported API to 1 or 2 and making rest as private functions.

-- Even before this series, except low level PM code, only one
common API was used to set the PD low power state.
int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)

-- Once we make OSWR as basic power state, we also avoid usage of
pwrdm_set_logic_retst() API.

-- We implement lock at this API and export only above API +
may be omap_get_pwrdm_state() kind of API based on need.

-- This solves the second requirement too.

Even if we have more requirement, they can be addressed
too without need of another layer.

If you look at the diffstat alone between two approaches, it is
evident how small piece of code is needed to support above.
Am not too much into the lines of code but basic objection we
have is not to add another glue layer.

Thinking bit loud, for the logical layer for power domain
we should move towards common device power domain
APIs and if needed add/enhance them to support OMAP.
   drivers/base/power/domain.c
May be this though is bit premature but the intetion is
to move towards generic linux framework.

> Anyway.  If there's a problem with this process, it sounds like you,
> Rajendra, Jean, Beno?t and I should schedule some time to talk over the
> same issues that you discussed with me on the phone.  Perhaps next week?
>
We can surely do a call if needed. But the comments given so far and the
RFC makes things more or less clear the contention point against the
$subject series.

Regards
Santosh

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

* Re: [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
  2012-08-16  5:50       ` Shilimkar, Santosh
@ 2012-09-10 15:09         ` Tero Kristo
  -1 siblings, 0 replies; 28+ messages in thread
From: Tero Kristo @ 2012-09-10 15:09 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: Paul Walmsley, Jean Pihet, Jean Pihet, linux-omap,
	linux-arm-kernel, khilman, Rajendra Nayak, Nishanth Menon

On Thu, 2012-08-16 at 11:20 +0530, Shilimkar, Santosh wrote:
> Paul,
> 
> On Thu, Aug 16, 2012 at 6:18 AM, Paul Walmsley <paul@pwsan.com> wrote:
> >
> > Hi Santosh,
> >
> > On Wed, 15 Aug 2012, Shilimkar, Santosh wrote:
> >
> > > On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com>
> > > wrote:
> > >
> > > I didn't find any mention here about why are we going in this path and
> > > not
> > > in the direction proposed in another RFC [1]
> > > I have already given my comments[2] against the introduction of another
> > > PD
> > > layer which can be avoided easily as demonstrated by the RFC[1]. The
> > > comments
> > > are still applicable for this series too.
> > >
> > > We really need to reduce OMAP specific framework overhead and
> > > move towards more generic PM frameworks. For me, this series is
> > > a step back-ward from that direction. Am really sorry for being critical
> > > again but I remain unconvinced about this series and the problem it
> > > is trying to solve.
> > >
> > > May be you have valid reasons not to follow the approach in [1] and in
> > > that case, it will be good to clarify that so that some of us get
> > > to know your rationale.
> >
> > I've asked Jean to handle the work of evaluating and/or integrating any
> > feedback from you and Rajendra into this series.  Jean, has this latest
> > series fully considered those issues?  Or are there still some areas of
> > misalignment / lack of clarity?
> >
> Thanks for the information. The main objection to this series was to
> not add un-necessary glue layer which still remains.
> 
> From our discussion in past on and off list, your main intention for such
> a series was -
> 
> 1. Need a way to support OSWR.
> - OSWR by definition is a RET with configurable logic and memory states.
> Its a true power state from PD point of view and its not a logical state.
> Now since we have agreed to make the OSWR as a static definition
> (in all products so far OSWR is used as a static definition with logic
> lost, memory retained kind of configuration.)
> 
> - The above requirement can be easily fixed by adding the OSWR
> as an additional basic power state as demonstrated in RFC.
> 
> - There is no need to add another glue layer for above.
> 
> 2. Locking so that the low level APIs don't race and henec abstracting the
> exported API to 1 or 2 and making rest as private functions.
> 
> -- Even before this series, except low level PM code, only one
> common API was used to set the PD low power state.
> int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
> 
> -- Once we make OSWR as basic power state, we also avoid usage of
> pwrdm_set_logic_retst() API.
> 
> -- We implement lock at this API and export only above API +
> may be omap_get_pwrdm_state() kind of API based on need.
> 
> -- This solves the second requirement too.
> 
> Even if we have more requirement, they can be addressed
> too without need of another layer.
> 
> If you look at the diffstat alone between two approaches, it is
> evident how small piece of code is needed to support above.
> Am not too much into the lines of code but basic objection we
> have is not to add another glue layer.
> 
> Thinking bit loud, for the logical layer for power domain
> we should move towards common device power domain
> APIs and if needed add/enhance them to support OMAP.
>    drivers/base/power/domain.c
> May be this though is bit premature but the intetion is
> to move towards generic linux framework.
> 
> > Anyway.  If there's a problem with this process, it sounds like you,
> > Rajendra, Jean, Benoît and I should schedule some time to talk over the
> > same issues that you discussed with me on the phone.  Perhaps next week?
> >
> We can surely do a call if needed. But the comments given so far and the
> RFC makes things more or less clear the contention point against the
> $subject series.

What is the latest status with this set? This is kind of blocking the
omap4 core retention feature also as I am supposed to put the patches on
top of this set. Do we have a consensus which way this set should
evolve?

Or, should I just base the core retention patches on top of baseline and
forget about the functional power states for now?

-Tero

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
@ 2012-09-10 15:09         ` Tero Kristo
  0 siblings, 0 replies; 28+ messages in thread
From: Tero Kristo @ 2012-09-10 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2012-08-16 at 11:20 +0530, Shilimkar, Santosh wrote:
> Paul,
> 
> On Thu, Aug 16, 2012 at 6:18 AM, Paul Walmsley <paul@pwsan.com> wrote:
> >
> > Hi Santosh,
> >
> > On Wed, 15 Aug 2012, Shilimkar, Santosh wrote:
> >
> > > On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com>
> > > wrote:
> > >
> > > I didn't find any mention here about why are we going in this path and
> > > not
> > > in the direction proposed in another RFC [1]
> > > I have already given my comments[2] against the introduction of another
> > > PD
> > > layer which can be avoided easily as demonstrated by the RFC[1]. The
> > > comments
> > > are still applicable for this series too.
> > >
> > > We really need to reduce OMAP specific framework overhead and
> > > move towards more generic PM frameworks. For me, this series is
> > > a step back-ward from that direction. Am really sorry for being critical
> > > again but I remain unconvinced about this series and the problem it
> > > is trying to solve.
> > >
> > > May be you have valid reasons not to follow the approach in [1] and in
> > > that case, it will be good to clarify that so that some of us get
> > > to know your rationale.
> >
> > I've asked Jean to handle the work of evaluating and/or integrating any
> > feedback from you and Rajendra into this series.  Jean, has this latest
> > series fully considered those issues?  Or are there still some areas of
> > misalignment / lack of clarity?
> >
> Thanks for the information. The main objection to this series was to
> not add un-necessary glue layer which still remains.
> 
> From our discussion in past on and off list, your main intention for such
> a series was -
> 
> 1. Need a way to support OSWR.
> - OSWR by definition is a RET with configurable logic and memory states.
> Its a true power state from PD point of view and its not a logical state.
> Now since we have agreed to make the OSWR as a static definition
> (in all products so far OSWR is used as a static definition with logic
> lost, memory retained kind of configuration.)
> 
> - The above requirement can be easily fixed by adding the OSWR
> as an additional basic power state as demonstrated in RFC.
> 
> - There is no need to add another glue layer for above.
> 
> 2. Locking so that the low level APIs don't race and henec abstracting the
> exported API to 1 or 2 and making rest as private functions.
> 
> -- Even before this series, except low level PM code, only one
> common API was used to set the PD low power state.
> int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
> 
> -- Once we make OSWR as basic power state, we also avoid usage of
> pwrdm_set_logic_retst() API.
> 
> -- We implement lock at this API and export only above API +
> may be omap_get_pwrdm_state() kind of API based on need.
> 
> -- This solves the second requirement too.
> 
> Even if we have more requirement, they can be addressed
> too without need of another layer.
> 
> If you look at the diffstat alone between two approaches, it is
> evident how small piece of code is needed to support above.
> Am not too much into the lines of code but basic objection we
> have is not to add another glue layer.
> 
> Thinking bit loud, for the logical layer for power domain
> we should move towards common device power domain
> APIs and if needed add/enhance them to support OMAP.
>    drivers/base/power/domain.c
> May be this though is bit premature but the intetion is
> to move towards generic linux framework.
> 
> > Anyway.  If there's a problem with this process, it sounds like you,
> > Rajendra, Jean, Beno?t and I should schedule some time to talk over the
> > same issues that you discussed with me on the phone.  Perhaps next week?
> >
> We can surely do a call if needed. But the comments given so far and the
> RFC makes things more or less clear the contention point against the
> $subject series.

What is the latest status with this set? This is kind of blocking the
omap4 core retention feature also as I am supposed to put the patches on
top of this set. Do we have a consensus which way this set should
evolve?

Or, should I just base the core retention patches on top of baseline and
forget about the functional power states for now?

-Tero

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

* Re: [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
  2012-09-10 15:09         ` Tero Kristo
@ 2012-09-11  7:50           ` Pihet-XID, Jean
  -1 siblings, 0 replies; 28+ messages in thread
From: Pihet-XID, Jean @ 2012-09-11  7:50 UTC (permalink / raw)
  To: t-kristo, Paul Walmsley
  Cc: khilman, Nishanth Menon, Rajendra Nayak, Jean Pihet, Shilimkar,
	Santosh, linux-omap, linux-arm-kernel

Hi Tero, Paul,

After discussion with Paul at LPC I produced a new version that we are
now internally reviewing.

Paul, what is your plan?

Regards,
Jean

On Mon, Sep 10, 2012 at 5:09 PM, Tero Kristo <t-kristo@ti.com> wrote:
> On Thu, 2012-08-16 at 11:20 +0530, Shilimkar, Santosh wrote:
>> Paul,
>>
>> On Thu, Aug 16, 2012 at 6:18 AM, Paul Walmsley <paul@pwsan.com> wrote:
>> >
>> > Hi Santosh,
>> >
>> > On Wed, 15 Aug 2012, Shilimkar, Santosh wrote:
>> >
>> > > On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com>
>> > > wrote:
>> > >
>> > > I didn't find any mention here about why are we going in this path and
>> > > not
>> > > in the direction proposed in another RFC [1]
>> > > I have already given my comments[2] against the introduction of another
>> > > PD
>> > > layer which can be avoided easily as demonstrated by the RFC[1]. The
>> > > comments
>> > > are still applicable for this series too.
>> > >
>> > > We really need to reduce OMAP specific framework overhead and
>> > > move towards more generic PM frameworks. For me, this series is
>> > > a step back-ward from that direction. Am really sorry for being critical
>> > > again but I remain unconvinced about this series and the problem it
>> > > is trying to solve.
>> > >
>> > > May be you have valid reasons not to follow the approach in [1] and in
>> > > that case, it will be good to clarify that so that some of us get
>> > > to know your rationale.
>> >
>> > I've asked Jean to handle the work of evaluating and/or integrating any
>> > feedback from you and Rajendra into this series.  Jean, has this latest
>> > series fully considered those issues?  Or are there still some areas of
>> > misalignment / lack of clarity?
>> >
>> Thanks for the information. The main objection to this series was to
>> not add un-necessary glue layer which still remains.
>>
>> From our discussion in past on and off list, your main intention for such
>> a series was -
>>
>> 1. Need a way to support OSWR.
>> - OSWR by definition is a RET with configurable logic and memory states.
>> Its a true power state from PD point of view and its not a logical state.
>> Now since we have agreed to make the OSWR as a static definition
>> (in all products so far OSWR is used as a static definition with logic
>> lost, memory retained kind of configuration.)
>>
>> - The above requirement can be easily fixed by adding the OSWR
>> as an additional basic power state as demonstrated in RFC.
>>
>> - There is no need to add another glue layer for above.
>>
>> 2. Locking so that the low level APIs don't race and henec abstracting the
>> exported API to 1 or 2 and making rest as private functions.
>>
>> -- Even before this series, except low level PM code, only one
>> common API was used to set the PD low power state.
>> int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
>>
>> -- Once we make OSWR as basic power state, we also avoid usage of
>> pwrdm_set_logic_retst() API.
>>
>> -- We implement lock at this API and export only above API +
>> may be omap_get_pwrdm_state() kind of API based on need.
>>
>> -- This solves the second requirement too.
>>
>> Even if we have more requirement, they can be addressed
>> too without need of another layer.
>>
>> If you look at the diffstat alone between two approaches, it is
>> evident how small piece of code is needed to support above.
>> Am not too much into the lines of code but basic objection we
>> have is not to add another glue layer.
>>
>> Thinking bit loud, for the logical layer for power domain
>> we should move towards common device power domain
>> APIs and if needed add/enhance them to support OMAP.
>>    drivers/base/power/domain.c
>> May be this though is bit premature but the intetion is
>> to move towards generic linux framework.
>>
>> > Anyway.  If there's a problem with this process, it sounds like you,
>> > Rajendra, Jean, Benoît and I should schedule some time to talk over the
>> > same issues that you discussed with me on the phone.  Perhaps next week?
>> >
>> We can surely do a call if needed. But the comments given so far and the
>> RFC makes things more or less clear the contention point against the
>> $subject series.
>
> What is the latest status with this set? This is kind of blocking the
> omap4 core retention feature also as I am supposed to put the patches on
> top of this set. Do we have a consensus which way this set should
> evolve?
>
> Or, should I just base the core retention patches on top of baseline and
> forget about the functional power states for now?
>
> -Tero
>

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

* [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states
@ 2012-09-11  7:50           ` Pihet-XID, Jean
  0 siblings, 0 replies; 28+ messages in thread
From: Pihet-XID, Jean @ 2012-09-11  7:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero, Paul,

After discussion with Paul at LPC I produced a new version that we are
now internally reviewing.

Paul, what is your plan?

Regards,
Jean

On Mon, Sep 10, 2012 at 5:09 PM, Tero Kristo <t-kristo@ti.com> wrote:
> On Thu, 2012-08-16 at 11:20 +0530, Shilimkar, Santosh wrote:
>> Paul,
>>
>> On Thu, Aug 16, 2012 at 6:18 AM, Paul Walmsley <paul@pwsan.com> wrote:
>> >
>> > Hi Santosh,
>> >
>> > On Wed, 15 Aug 2012, Shilimkar, Santosh wrote:
>> >
>> > > On Wed, Aug 15, 2012 at 3:32 PM, Jean Pihet <jean.pihet@newoldbits.com>
>> > > wrote:
>> > >
>> > > I didn't find any mention here about why are we going in this path and
>> > > not
>> > > in the direction proposed in another RFC [1]
>> > > I have already given my comments[2] against the introduction of another
>> > > PD
>> > > layer which can be avoided easily as demonstrated by the RFC[1]. The
>> > > comments
>> > > are still applicable for this series too.
>> > >
>> > > We really need to reduce OMAP specific framework overhead and
>> > > move towards more generic PM frameworks. For me, this series is
>> > > a step back-ward from that direction. Am really sorry for being critical
>> > > again but I remain unconvinced about this series and the problem it
>> > > is trying to solve.
>> > >
>> > > May be you have valid reasons not to follow the approach in [1] and in
>> > > that case, it will be good to clarify that so that some of us get
>> > > to know your rationale.
>> >
>> > I've asked Jean to handle the work of evaluating and/or integrating any
>> > feedback from you and Rajendra into this series.  Jean, has this latest
>> > series fully considered those issues?  Or are there still some areas of
>> > misalignment / lack of clarity?
>> >
>> Thanks for the information. The main objection to this series was to
>> not add un-necessary glue layer which still remains.
>>
>> From our discussion in past on and off list, your main intention for such
>> a series was -
>>
>> 1. Need a way to support OSWR.
>> - OSWR by definition is a RET with configurable logic and memory states.
>> Its a true power state from PD point of view and its not a logical state.
>> Now since we have agreed to make the OSWR as a static definition
>> (in all products so far OSWR is used as a static definition with logic
>> lost, memory retained kind of configuration.)
>>
>> - The above requirement can be easily fixed by adding the OSWR
>> as an additional basic power state as demonstrated in RFC.
>>
>> - There is no need to add another glue layer for above.
>>
>> 2. Locking so that the low level APIs don't race and henec abstracting the
>> exported API to 1 or 2 and making rest as private functions.
>>
>> -- Even before this series, except low level PM code, only one
>> common API was used to set the PD low power state.
>> int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
>>
>> -- Once we make OSWR as basic power state, we also avoid usage of
>> pwrdm_set_logic_retst() API.
>>
>> -- We implement lock at this API and export only above API +
>> may be omap_get_pwrdm_state() kind of API based on need.
>>
>> -- This solves the second requirement too.
>>
>> Even if we have more requirement, they can be addressed
>> too without need of another layer.
>>
>> If you look at the diffstat alone between two approaches, it is
>> evident how small piece of code is needed to support above.
>> Am not too much into the lines of code but basic objection we
>> have is not to add another glue layer.
>>
>> Thinking bit loud, for the logical layer for power domain
>> we should move towards common device power domain
>> APIs and if needed add/enhance them to support OMAP.
>>    drivers/base/power/domain.c
>> May be this though is bit premature but the intetion is
>> to move towards generic linux framework.
>>
>> > Anyway.  If there's a problem with this process, it sounds like you,
>> > Rajendra, Jean, Beno?t and I should schedule some time to talk over the
>> > same issues that you discussed with me on the phone.  Perhaps next week?
>> >
>> We can surely do a call if needed. But the comments given so far and the
>> RFC makes things more or less clear the contention point against the
>> $subject series.
>
> What is the latest status with this set? This is kind of blocking the
> omap4 core retention feature also as I am supposed to put the patches on
> top of this set. Do we have a consensus which way this set should
> evolve?
>
> Or, should I just base the core retention patches on top of baseline and
> forget about the functional power states for now?
>
> -Tero
>

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

end of thread, other threads:[~2012-09-11  7:50 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-15 10:02 [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states Jean Pihet
2012-08-15 10:02 ` Jean Pihet
2012-08-15 10:02 ` [PATCH 1/8] ARM: OMAP2+: PM: introduce " Jean Pihet
2012-08-15 10:02   ` Jean Pihet
2012-08-15 10:02 ` [PATCH 2/8] ARM: OMAP2+: PM: introduce power domains achievable " Jean Pihet
2012-08-15 10:02   ` Jean Pihet
2012-08-15 10:02 ` [PATCH 3/8] ARM: OMAP2+: PM: add a lock to protect the powerdomains next state Jean Pihet
2012-08-15 10:02   ` Jean Pihet
2012-08-15 10:02 ` [PATCH 4/8] ARM: OMAP2+: PM: use the functional power states API Jean Pihet
2012-08-15 10:02   ` Jean Pihet
2012-08-15 10:02 ` [PATCH 5/8] ARM: OMAP2+: PM: use power domain functional state in stats counters Jean Pihet
2012-08-15 10:02   ` Jean Pihet
2012-08-15 10:02 ` [PATCH 6/8] ARM: OMAP2+: PM debug: trace the functional power domains states Jean Pihet
2012-08-15 10:02   ` Jean Pihet
2012-08-15 10:02 ` [PATCH 7/8] ARM: OMAP2+: powerdomain: add error logs Jean Pihet
2012-08-15 10:02   ` Jean Pihet
2012-08-15 10:02 ` [PATCH 8/8] ARM: OMAP2+: PM: reorganize the powerdomain API in public and private parts Jean Pihet
2012-08-15 10:02   ` Jean Pihet
2012-08-15 17:05 ` [PATCH v5 0/8] ARM: OMAP2+: PM: introduce the power domains functional states Shilimkar, Santosh
2012-08-15 17:05   ` Shilimkar, Santosh
2012-08-16  0:48   ` Paul Walmsley
2012-08-16  0:48     ` Paul Walmsley
2012-08-16  5:50     ` Shilimkar, Santosh
2012-08-16  5:50       ` Shilimkar, Santosh
2012-09-10 15:09       ` Tero Kristo
2012-09-10 15:09         ` Tero Kristo
2012-09-11  7:50         ` Pihet-XID, Jean
2012-09-11  7:50           ` Pihet-XID, Jean

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.