[PATCH 09/10] ARM: OMAP2+: clockdomain: convert existing atomic usecounts into spinlock-protected shorts/ints

2012-12-08 Thread Paul Walmsley
The atomic usecounts seem to be confusing, and are no longer needed
since the operations that they are attached to really should take
place under lock.  Replace the atomic counters with simple integers,
protected by the enclosing powerdomain spinlock.

Signed-off-by: Paul Walmsley 
Cc: Kevin Hilman 
---
 arch/arm/mach-omap2/clockdomain.c  |   88 +++-
 arch/arm/mach-omap2/clockdomain.h  |6 +-
 arch/arm/mach-omap2/cm3xxx.c   |6 +-
 arch/arm/mach-omap2/cminst44xx.c   |2 -
 arch/arm/mach-omap2/pm-debug.c |6 +-
 arch/arm/mach-omap2/pm.c   |3 +
 arch/arm/mach-omap2/prm2xxx_3xxx.c |3 +
 7 files changed, 88 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c 
b/arch/arm/mach-omap2/clockdomain.c
index 9d5b69f..ed8ac2f 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -210,7 +210,8 @@ static int _clkdm_add_wkdep(struct clockdomain *clkdm1,
return ret;
}
 
-   if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
+   cd->wkdep_usecount++;
+   if (cd->wkdep_usecount == 1) {
pr_debug("clockdomain: hardware will wake up %s when %s wakes 
up\n",
 clkdm1->name, clkdm2->name);
 
@@ -252,7 +253,8 @@ static int _clkdm_del_wkdep(struct clockdomain *clkdm1,
return ret;
}
 
-   if (atomic_dec_return(&cd->wkdep_usecount) == 0) {
+   cd->wkdep_usecount--;
+   if (cd->wkdep_usecount == 0) {
pr_debug("clockdomain: hardware will no longer wake up %s after 
%s wakes up\n",
 clkdm1->name, clkdm2->name);
 
@@ -296,7 +298,8 @@ static int _clkdm_add_sleepdep(struct clockdomain *clkdm1,
return ret;
}
 
-   if (atomic_inc_return(&cd->sleepdep_usecount) == 1) {
+   cd->sleepdep_usecount++;
+   if (cd->sleepdep_usecount == 1) {
pr_debug("clockdomain: will prevent %s from sleeping if %s is 
active\n",
 clkdm1->name, clkdm2->name);
 
@@ -340,7 +343,8 @@ static int _clkdm_del_sleepdep(struct clockdomain *clkdm1,
return ret;
}
 
-   if (atomic_dec_return(&cd->sleepdep_usecount) == 0) {
+   cd->sleepdep_usecount--;
+   if (cd->sleepdep_usecount == 0) {
pr_debug("clockdomain: will no longer prevent %s from sleeping 
if %s is active\n",
 clkdm1->name, clkdm2->name);
 
@@ -567,7 +571,21 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain 
*clkdm)
  */
 int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
-   return _clkdm_add_wkdep(clkdm1, clkdm2);
+   struct clkdm_dep *cd;
+   int ret;
+
+   if (!clkdm1 || !clkdm2)
+   return -EINVAL;
+
+   cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+   if (IS_ERR(cd))
+   return PTR_ERR(cd);
+
+   pwrdm_lock(cd->clkdm->pwrdm.ptr);
+   ret = _clkdm_add_wkdep(clkdm1, clkdm2);
+   pwrdm_unlock(cd->clkdm->pwrdm.ptr);
+
+   return ret;
 }
 
 /**
@@ -582,7 +600,21 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct 
clockdomain *clkdm2)
  */
 int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
-   return _clkdm_del_wkdep(clkdm1, clkdm2);
+   struct clkdm_dep *cd;
+   int ret;
+
+   if (!clkdm1 || !clkdm2)
+   return -EINVAL;
+
+   cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+   if (IS_ERR(cd))
+   return PTR_ERR(cd);
+
+   pwrdm_lock(cd->clkdm->pwrdm.ptr);
+   ret = _clkdm_del_wkdep(clkdm1, clkdm2);
+   pwrdm_unlock(cd->clkdm->pwrdm.ptr);
+
+   return ret;
 }
 
 /**
@@ -620,7 +652,7 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct 
clockdomain *clkdm2)
return ret;
}
 
-   /* XXX It's faster to return the atomic wkdep_usecount */
+   /* XXX It's faster to return the wkdep_usecount */
return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);
 }
 
@@ -659,7 +691,21 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
  */
 int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
-   return _clkdm_add_sleepdep(clkdm1, clkdm2);
+   struct clkdm_dep *cd;
+   int ret;
+
+   if (!clkdm1 || !clkdm2)
+   return -EINVAL;
+
+   cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+   if (IS_ERR(cd))
+   return PTR_ERR(cd);
+
+   pwrdm_lock(cd->clkdm->pwrdm.ptr);
+   ret = _clkdm_add_sleepdep(clkdm1, clkdm2);
+   pwrdm_unlock(cd->clkdm->pwrdm.ptr);
+
+   return ret;
 }
 
 /**
@@ -676,7 +722,21 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct 
clockdomain *clkdm2)
  */
 int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
-   return _clkdm_del_sleepdep(clkdm1, clkdm2);
+   struct clkdm_dep *cd;
+   int ret;

[PATCH 04/10] ARM: OMAP2: PM/powerdomain: drop unnecessary pwrdm_wait_transition()

2012-12-08 Thread Paul Walmsley
Drop an unnecessary pwrdm_wait_transition() from mach-omap2/pm.c -
it's called by the subsequent pwrdm_state_switch().

Also get rid of pwrdm_wait_transition() in the powerdomain code - there's
no longer any need to export this function.

Signed-off-by: Paul Walmsley 
Cc: Kevin Hilman 
---
 arch/arm/mach-omap2/pm.c  |1 -
 arch/arm/mach-omap2/powerdomain.c |   30 +-
 arch/arm/mach-omap2/powerdomain.h |2 --
 3 files changed, 5 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 331478f..cc8ed0f 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -139,7 +139,6 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 
pwrst)
break;
case LOWPOWERSTATE_SWITCH:
pwrdm_set_lowpwrstchange(pwrdm);
-   pwrdm_wait_transition(pwrdm);
pwrdm_state_switch(pwrdm);
break;
}
diff --git a/arch/arm/mach-omap2/powerdomain.c 
b/arch/arm/mach-omap2/powerdomain.c
index 92388c0..97b3881 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -112,7 +112,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
for (i = 0; i < pwrdm->banks; i++)
pwrdm->ret_mem_off_counter[i] = 0;
 
-   pwrdm_wait_transition(pwrdm);
+   arch_pwrdm->pwrdm_wait_transition(pwrdm);
pwrdm->state = pwrdm_read_pwrst(pwrdm);
pwrdm->state_counter[pwrdm->state] = 1;
 
@@ -950,34 +950,14 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
return ret;
 }
 
-/**
- * pwrdm_wait_transition - wait for powerdomain power transition to finish
- * @pwrdm: struct powerdomain * to wait for
- *
- * If the powerdomain @pwrdm is in the process of a state transition,
- * spin until it completes the power transition, or until an iteration
- * bailout value is reached. Returns -EINVAL if the powerdomain
- * pointer is null, -EAGAIN if the bailout value was reached, or
- * returns 0 upon success.
- */
-int pwrdm_wait_transition(struct powerdomain *pwrdm)
-{
-   int ret = -EINVAL;
-
-   if (!pwrdm)
-   return -EINVAL;
-
-   if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
-   ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
-
-   return ret;
-}
-
 int pwrdm_state_switch(struct powerdomain *pwrdm)
 {
int ret;
 
-   ret = pwrdm_wait_transition(pwrdm);
+   if (!pwrdm || !arch_pwrdm)
+   return -EINVAL;
+
+   ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
if (!ret)
ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
 
diff --git a/arch/arm/mach-omap2/powerdomain.h 
b/arch/arm/mach-omap2/powerdomain.h
index 5277d56eb..7c1534b 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -225,8 +225,6 @@ 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);


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


[PATCH 03/10] ARM: OMAP2xxx: PM: clean up some crufty powerstate programming code

2012-12-08 Thread Paul Walmsley
Don't attempt to put clockdomains to sleep; this should be handled by the
clock framework.  It should be enough to program the next-power-state,
and then let the code in omap_pm_clkdms_setup() deal with the rest.

Start out by programming the MPU and CORE powerdomains to stay ON.
Then control the MPU and CORE powerdomain states directly in
omap2_enter_full_retention() and omap2_enter_mpu_retention().  Not the
most optimal way to do it, but certainly is the most conservative until
OMAP2xxx PM is working again.

Get rid of the open-coded PM_PWSTCTRL_MPU writes in
omap2_enter_mpu_retention(); use the powerdomain code instead.

Signed-off-by: Paul Walmsley 
Cc: Kevin Hilman 
---
 arch/arm/mach-omap2/pm24xx.c |   30 ++
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 83815dd..4c06d8a 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -89,11 +89,7 @@ static int omap2_enter_full_retention(void)
omap2_prm_write_mod_reg(0x, CORE_MOD, OMAP24XX_PM_WKST2);
omap2_prm_write_mod_reg(0x, WKUP_MOD, PM_WKST);
 
-   /*
-* 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(core_pwrdm, PWRDM_POWER_RET);
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
 
/* Workaround to kill USB */
@@ -136,6 +132,9 @@ no_sleep:
/* Mask future PRCM-to-MPU interrupts */
omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
 
+   pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
+   pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_ON);
+
return 0;
 }
 
@@ -185,17 +184,16 @@ static void omap2_enter_mpu_retention(void)
omap2_prm_write_mod_reg(0x, WKUP_MOD, PM_WKST);
 
/* Try to enter MPU retention */
-   omap2_prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
- OMAP_LOGICRETSTATE_MASK,
- MPU_MOD, OMAP2_PM_PWSTCTRL);
+   pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
+
} else {
/* Block MPU retention */
-
-   omap2_prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK, MPU_MOD,
-OMAP2_PM_PWSTCTRL);
+   pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
}
 
omap2_sram_idle();
+
+   pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
 }
 
 static int omap2_can_sleep(void)
@@ -250,25 +248,17 @@ static void __init prcm_setup_regs(void)
for (i = 0; i < num_mem_banks; i++)
pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET);
 
-   /* Set CORE powerdomain's next power state to RETENTION */
-   pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);
+   pwrdm_set_logic_retst(core_pwrdm, PWRDM_POWER_RET);
 
-   /*
-* 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);
 
/* Force-power down DSP, GFX powerdomains */
 
pwrdm = clkdm_get_pwrdm(dsp_clkdm);
pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
-   clkdm_sleep(dsp_clkdm);
 
pwrdm = clkdm_get_pwrdm(gfx_clkdm);
pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
-   clkdm_sleep(gfx_clkdm);
 
/* Enable hardware-supervised idle for all clkdms */
clkdm_for_each(omap_pm_clkdms_setup, NULL);


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


[PATCH 00/10] ARM: OMAP2+: second set of PM fixes and cleanup for 3.9

2012-12-08 Thread Paul Walmsley
Several more OMAP2+ power management fixes, optimizations, and
cleanup, intended for 3.9.  This series is also a prerequisite for the
functional powerdomain conversion series.

I'll plan to bundle these patches together into a pull request with the first
set of 3.9 PM patches, sent earlier.

- Paul

---

vmlinux object size
(delta in bytes from TEST_pm_cleanup_fixes_a_3.9 
(8f5e20850396fc60fd4ee01f586705033902bb53)):
   text data  bsstotal  kernel
   +460 -3680  +92  am33xx_only
   +200 -4640 -264  n800_multi_omap2xxx
   +192 -1440  +48  n800_only_a
  0000  omap1_defconfig
  0000  omap1_defconfig_1510innovator_only
  0000  omap1_defconfig_5912osk_only
   +296-18160-1520  omap2plus_defconfig
   +272 -1760  +96  omap2plus_defconfig_2430sdp_only
   +232-18160-1584  omap2plus_defconfig_cpupm
   +280-15200-1240  omap2plus_defconfig_no_pm
  +4388-10160+3372  omap2plus_defconfig_omap2_4_only
   +468 -9520 -484  omap2plus_defconfig_omap3_4_only
   +700 -584 -144  -28  rmk_omap3430_ldp_allnoconfig
   +452 -6480 -196  rmk_omap3430_ldp_oldconfig
   +700 -584 -144  -28  rmk_omap4430_sdp_allnoconfig
   +424 -3280  +96  rmk_omap4430_sdp_oldconfig

Boot-time memory difference
(delta in bytes from TEST_pm_cleanup_fixes_a_3.9 
(8f5e20850396fc60fd4ee01f586705033902bb53))
  avail  rsrvd   high  freed  board  kconfig
 4k-4k  .  .  2430sdpomap2plus_defconfig
 4k-4k  .  .  3517evmomap2plus_defconfig
 4k-4k  .  .  3530es3beagle  omap2plus_defconfig
 4k-4k  .  .  3730beaglexm   omap2plus_defconfig
 4k-4k  .  .  37xxevmomap2plus_defconfig
 4k-4k  .  .  4430es2panda   omap2plus_defconfig
 4k-4k  .  .  cmt3517omap2plus_defconfig

Paul Walmsley (10):
  ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
  ARM: OMAP2+: clockdomain: add pwrdm_state_switch() call to clkdm_sleep()
  ARM: OMAP2xxx: PM: clean up some crufty powerstate programming code
  ARM: OMAP2: PM/powerdomain: drop unnecessary pwrdm_wait_transition()
  ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain 
code
  ARM: OMAP2+: powerdomain/clockdomain: add a per-powerdomain spinlock
  ARM: OMAP2xxx: CM: remove autodep handling
  ARM: OMAP2+: clockdomain: work on wkdep/sleepdep functions
  ARM: OMAP2+: clockdomain: convert existing atomic usecounts into 
spinlock-protected shorts/ints
  ARM: OMAP2+: powerdomain: fix whitespace, improve flag comments


 arch/arm/mach-omap2/clockdomain-powerdomain.h|   22 +
 arch/arm/mach-omap2/clockdomain.c|  550 +++---
 arch/arm/mach-omap2/clockdomain.h|   17 -
 arch/arm/mach-omap2/cm2xxx.c |   33 -
 arch/arm/mach-omap2/cm3xxx.c |   14 -
 arch/arm/mach-omap2/cminst44xx.c |2 
 arch/arm/mach-omap2/cpuidle34xx.c|   14 -
 arch/arm/mach-omap2/cpuidle44xx.c|   28 +
 arch/arm/mach-omap2/pm-debug.c   |6 
 arch/arm/mach-omap2/pm.c |   65 ---
 arch/arm/mach-omap2/pm.h |1 
 arch/arm/mach-omap2/pm24xx.c |   30 -
 arch/arm/mach-omap2/powerdomain-clockdomain.h|   27 +
 arch/arm/mach-omap2/powerdomain.c|  176 +--
 arch/arm/mach-omap2/powerdomain.h|   42 +-
 arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c |4 
 arch/arm/mach-omap2/powerdomains2xxx_data.c  |8 
 arch/arm/mach-omap2/powerdomains3xxx_data.c  |   44 +-
 arch/arm/mach-omap2/prm2xxx_3xxx.c   |3 
 19 files changed, 661 insertions(+), 425 deletions(-)
 create mode 100644 arch/arm/mach-omap2/clockdomain-powerdomain.h
 create mode 100644 arch/arm/mach-omap2/powerdomain-clockdomain.h

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


[PATCH 01/10] ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings

2012-12-08 Thread Paul Walmsley
Fix the following sparse warnings in the OMAP3/4 CPUIdle code:

arch/arm/mach-omap2/cpuidle34xx.c:272:1: warning: symbol 'omap3_idle_dev' was 
not declared. Should it be static?
arch/arm/mach-omap2/cpuidle34xx.c:274:23: warning: symbol 'omap3_idle_driver' 
was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle44xx.c:164:1: warning: symbol 'omap4_idle_dev' was 
not declared. Should it be static?
arch/arm/mach-omap2/cpuidle44xx.c:166:23: warning: symbol 'omap4_idle_driver' 
was not declared. Should it be static?

Also fix the following checkpatch warnings:

WARNING: please, no space before tabs
#44: FILE: arch/arm/mach-omap2/cpuidle34xx.c:105:
+^I.name = ^I"omap3_idle",$

WARNING: please, no space before tabs
#45: FILE: arch/arm/mach-omap2/cpuidle34xx.c:106:
+^I.owner = ^ITHIS_MODULE,$

ERROR: code indent should use tabs where possible
#211: FILE: arch/arm/mach-omap2/cpuidle44xx.c:74:
+/* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */$


Signed-off-by: Paul Walmsley 
Cc: Kevin Hilman 
---
 arch/arm/mach-omap2/cpuidle34xx.c |   14 +-
 arch/arm/mach-omap2/cpuidle44xx.c |   28 
 2 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
b/arch/arm/mach-omap2/cpuidle34xx.c
index ad70220..e6215b5 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -53,6 +53,8 @@ struct omap3_idle_statedata {
  */
 #define OMAP_CPUIDLE_CX_NO_CLKDM_IDLE  BIT(0)
 
+static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
+
 /*
  * Prevent PER OFF if CORE is not in RETention or OFF as this would
  * disable PER wakeups completely.
@@ -97,7 +99,7 @@ static struct omap3_idle_statedata omap3_idle_data[] = {
},
 };
 
-static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
+/* Private functions */
 
 static int __omap3_enter_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
@@ -269,11 +271,11 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
return ret;
 }
 
-DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
+static DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
 
-struct cpuidle_driver omap3_idle_driver = {
-   .name = "omap3_idle",
-   .owner =THIS_MODULE,
+static struct cpuidle_driver omap3_idle_driver = {
+   .name = "omap3_idle",
+   .owner =THIS_MODULE,
.states = {
{
.enter= omap3_enter_idle_bm,
@@ -336,6 +338,8 @@ struct cpuidle_driver omap3_idle_driver = {
.safe_state_index = 0,
 };
 
+/* Public functions */
+
 /**
  * omap3_idle_init - Init routine for OMAP3 idle
  *
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c 
b/arch/arm/mach-omap2/cpuidle44xx.c
index 288bee6..d639aef 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -54,6 +54,8 @@ static struct clockdomain *cpu_clkdm[NR_CPUS];
 static atomic_t abort_barrier;
 static bool cpu_done[NR_CPUS];
 
+/* Private functions */
+
 /**
  * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions
  * @dev: cpuidle device
@@ -161,9 +163,19 @@ fail:
return index;
 }
 
-DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
+/*
+ * For each cpu, setup the broadcast timer because local timers
+ * stops for the states above C1.
+ */
+static void omap_setup_broadcast_timer(void *arg)
+{
+   int cpu = smp_processor_id();
+   clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
+}
+
+static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
 
-struct cpuidle_driver omap4_idle_driver = {
+static struct cpuidle_driver omap4_idle_driver = {
.name   = "omap4_idle",
.owner  = THIS_MODULE,
.en_core_tk_irqen   = 1,
@@ -178,7 +190,7 @@ struct cpuidle_driver omap4_idle_driver = {
.desc = "MPUSS ON"
},
{
-/* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
+   /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
.exit_latency = 328 + 440,
.target_residency = 960,
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
@@ -200,15 +212,7 @@ struct cpuidle_driver omap4_idle_driver = {
.safe_state_index = 0,
 };
 
-/*
- * For each cpu, setup the broadcast timer because local timers
- * stops for the states above C1.
- */
-static void omap_setup_broadcast_timer(void *arg)
-{
-   int cpu = smp_processor_id();
-   clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
-}
+/* Public functions */
 
 /**
  * omap4_idle_init - Init routine for OMAP4 idle


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

[PATCH 02/10] ARM: OMAP2+: clockdomain: add pwrdm_state_switch() call to clkdm_sleep()

2012-12-08 Thread Paul Walmsley
In clkdm_sleep(), the powerdomain should be eligible to switch power
states right after the call to the low-level clockdomain sleep
function.  We should have been tracking that with the
pwrdm_state_switch() code, but we weren't, for whatever reason.  Fix that.

Signed-off-by: Paul Walmsley 
---
 arch/arm/mach-omap2/clockdomain.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-omap2/clockdomain.c 
b/arch/arm/mach-omap2/clockdomain.c
index 64e5046..18f65fd 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -763,6 +763,7 @@ int clkdm_sleep(struct clockdomain *clkdm)
spin_lock_irqsave(&clkdm->lock, flags);
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
ret = arch_clkdm->clkdm_sleep(clkdm);
+   ret |= pwrdm_state_switch(clkdm->pwrdm.ptr);
spin_unlock_irqrestore(&clkdm->lock, flags);
return ret;
 }


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


[PATCH 08/10] ARM: OMAP2+: clockdomain: work on wkdep/sleepdep functions

2012-12-08 Thread Paul Walmsley
Split the clkdm_(add|del)_(wk|sleep)dep() functions into lockless and
locking versions -- this will be needed in a subsequent patch.  Also,
while here, remove the leading underscore, since these are not
currently static functions.  And for functions that have
kerneldoc-style comment blocks, but which are missing the initial
'/**' tag, fix the tag to indicate that they are kerneldoc.

Signed-off-by: Paul Walmsley 
---
 arch/arm/mach-omap2/clockdomain.c |  394 ++---
 arch/arm/mach-omap2/clockdomain.h |5 
 arch/arm/mach-omap2/cm3xxx.c  |8 -
 3 files changed, 240 insertions(+), 167 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c 
b/arch/arm/mach-omap2/clockdomain.c
index 2142dab..9d5b69f 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -120,7 +120,7 @@ static struct clkdm_dep *_clkdm_deps_lookup(struct 
clockdomain *clkdm,
return cd;
 }
 
-/*
+/**
  * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store
  * @autodep: struct clkdm_autodep * to resolve
  *
@@ -152,88 +152,202 @@ static void _autodep_lookup(struct clkdm_autodep 
*autodep)
autodep->clkdm.ptr = clkdm;
 }
 
-/*
- * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable
- * @clkdm: struct clockdomain *
+/**
+ * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms
+ * @clkdm: clockdomain that we are resolving dependencies for
+ * @clkdm_deps: ptr to array of struct clkdm_deps to resolve
  *
- * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm'
- * in hardware-supervised mode.  Meant to be called from clock framework
- * when a clock inside clockdomain 'clkdm' is enabled. No return value.
+ * Iterates through @clkdm_deps, looking up the struct clockdomain named by
+ * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep.
+ * No return value.
+ */
+static void _resolve_clkdm_deps(struct clockdomain *clkdm,
+   struct clkdm_dep *clkdm_deps)
+{
+   struct clkdm_dep *cd;
+
+   for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) {
+   if (cd->clkdm)
+   continue;
+   cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
+   WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s 
while resolving dependencies - should never happen",
+clkdm->name, cd->clkdm_name);
+   }
+}
+
+/**
+ * _clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1 (lockless)
+ * @clkdm1: wake this struct clockdomain * up (dependent)
+ * @clkdm2: when this struct clockdomain * wakes up (source)
  *
- * XXX autodeps are deprecated and should be removed at the earliest
- * opportunity
+ * When the clockdomain represented by @clkdm2 wakes up, wake up
+ * @clkdm1. Implemented in hardware on the OMAP, this feature is
+ * designed to reduce wakeup latency of the dependent clockdomain @clkdm1.
+ * Returns -EINVAL if presented with invalid clockdomain pointers,
+ * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon
+ * success.
  */
-void _clkdm_add_autodeps(struct clockdomain *clkdm)
+static int _clkdm_add_wkdep(struct clockdomain *clkdm1,
+   struct clockdomain *clkdm2)
 {
-   struct clkdm_autodep *autodep;
+   struct clkdm_dep *cd;
+   int ret = 0;
 
-   if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
-   return;
+   if (!clkdm1 || !clkdm2)
+   return -EINVAL;
 
-   for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
-   if (IS_ERR(autodep->clkdm.ptr))
-   continue;
+   cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+   if (IS_ERR(cd))
+   ret = PTR_ERR(cd);
 
-   pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n",
-clkdm->name, autodep->clkdm.ptr->name);
+   if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep)
+   ret = -EINVAL;
 
-   clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr);
-   clkdm_add_wkdep(clkdm, autodep->clkdm.ptr);
+   if (ret) {
+   pr_debug("clockdomain: hardware cannot set/clear wake up of %s 
when %s wakes up\n",
+clkdm1->name, clkdm2->name);
+   return ret;
+   }
+
+   if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
+   pr_debug("clockdomain: hardware will wake up %s when %s wakes 
up\n",
+clkdm1->name, clkdm2->name);
+
+   ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
}
+
+   return ret;
 }
 
-/*
- * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm
- * @clkdm: struct clockdomain *
+/**
+ * _clkdm_del_wkdep - remove a wakeup dep from clkdm2 to clkdm1 (lockless)
+ * @clkdm1: wake this struct clockdomain * up (dependent)
+ * @clkdm2: when this struct clockdomain * wakes up (source)
  *
- * Remove

[PATCH 07/10] ARM: OMAP2xxx: CM: remove autodep handling

2012-12-08 Thread Paul Walmsley
There's no need to preserve the autodep handling code in
mach-omap2/cm2xxx.c, since no autodeps are defined for these chips.
Hopefully they'll never be needed, but if in some future case they are,
this code can be added back in.

Signed-off-by: Paul Walmsley 
---
 arch/arm/mach-omap2/cm2xxx.c |   33 -
 1 file changed, 4 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index db65069..6774a53 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -273,9 +273,6 @@ int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 
idlest_id, u8 idlest_shift)
 
 static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)
 {
-   if (atomic_read(&clkdm->usecount) > 0)
-   _clkdm_add_autodeps(clkdm);
-
omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
   clkdm->clktrctrl_mask);
 }
@@ -284,9 +281,6 @@ static void omap2xxx_clkdm_deny_idle(struct clockdomain 
*clkdm)
 {
omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);
-
-   if (atomic_read(&clkdm->usecount) > 0)
-   _clkdm_del_autodeps(clkdm);
 }
 
 static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
@@ -298,18 +292,8 @@ static int omap2xxx_clkdm_clk_enable(struct clockdomain 
*clkdm)
 
hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
  clkdm->clktrctrl_mask);
-
-   if (hwsup) {
-   /* Disable HW transitions when we are changing deps */
-   omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-   clkdm->clktrctrl_mask);
-   _clkdm_add_autodeps(clkdm);
-   omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-  clkdm->clktrctrl_mask);
-   } else {
-   if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-   omap2xxx_clkdm_wakeup(clkdm);
-   }
+   if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+   omap2xxx_clkdm_wakeup(clkdm);
 
return 0;
 }
@@ -324,17 +308,8 @@ static int omap2xxx_clkdm_clk_disable(struct clockdomain 
*clkdm)
hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
  clkdm->clktrctrl_mask);
 
-   if (hwsup) {
-   /* Disable HW transitions when we are changing deps */
-   omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-   clkdm->clktrctrl_mask);
-   _clkdm_del_autodeps(clkdm);
-   omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-  clkdm->clktrctrl_mask);
-   } else {
-   if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
-   omap2xxx_clkdm_sleep(clkdm);
-   }
+   if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+   omap2xxx_clkdm_sleep(clkdm);
 
return 0;
 }


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


[PATCH 10/10] ARM: OMAP2+: powerdomain: fix whitespace, improve flag comments

2012-12-08 Thread Paul Walmsley
Fix some whitespace problems introduced by commit
da03ce65b5431245b9cd20db3edaaa6b9f5c8dc1 ("OMAP3: powerdomain data:
add voltage domains").  Also, improve the documentation for the struct
powerdomain.flags field.

Signed-off-by: Paul Walmsley 
Cc: Kevin Hilman 
---
 arch/arm/mach-omap2/powerdomain.h|   26 +++--
 arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c |4 +-
 arch/arm/mach-omap2/powerdomains2xxx_data.c  |8 ++--
 arch/arm/mach-omap2/powerdomains3xxx_data.c  |   44 +++---
 4 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.h 
b/arch/arm/mach-omap2/powerdomain.h
index 83b4892..842ba46 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -43,18 +43,20 @@
 #define PWRSTS_OFF_RET_ON  (PWRSTS_OFF_RET | PWRSTS_ON)
 
 
-/* Powerdomain flags */
-#define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */
-#define PWRDM_HAS_MPU_QUIRK(1 << 1) /* MPU pwr domain has MEM bank 0 bits
- * in MEM bank 1 position. This is
- * true for OMAP3430
- */
-#define PWRDM_HAS_LOWPOWERSTATECHANGE  (1 << 2) /*
- * support to transition from a
- * sleep state to a lower sleep
- * state without waking up the
- * powerdomain
- */
+/*
+ * Powerdomain flags (struct powerdomain.flags)
+ *
+ * PWRDM_HAS_HDWR_SAR - powerdomain has hardware save-and-restore support
+ *
+ * PWRDM_HAS_MPU_QUIRK - MPU pwr domain has MEM bank 0 bits in MEM
+ * bank 1 position. This is true for OMAP3430
+ *
+ * PWRDM_HAS_LOWPOWERSTATECHANGE - can transition from a sleep state
+ * to a lower sleep state without waking up the powerdomain
+ */
+#define PWRDM_HAS_HDWR_SAR BIT(0)
+#define PWRDM_HAS_MPU_QUIRKBIT(1)
+#define PWRDM_HAS_LOWPOWERSTATECHANGE  BIT(2)
 
 /*
  * Number of memory banks that are power-controllable. On OMAP4430, the
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c 
b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
index d3a5399..7b946f1 100644
--- a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
@@ -54,12 +54,12 @@ struct powerdomain gfx_omap2_pwrdm = {
.pwrsts_mem_on= {
[0] = PWRSTS_ON,  /* MEMONSTATE */
},
-   .voltdm   = { .name = "core" },
+   .voltdm   = { .name = "core" },
 };
 
 struct powerdomain wkup_omap2_pwrdm = {
.name   = "wkup_pwrdm",
.prcm_offs  = WKUP_MOD,
.pwrsts = PWRSTS_ON,
-   .voltdm = { .name = "wakeup" },
+   .voltdm = { .name = "wakeup" },
 };
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c 
b/arch/arm/mach-omap2/powerdomains2xxx_data.c
index 01abc1e..578eef8 100644
--- a/arch/arm/mach-omap2/powerdomains2xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c
@@ -38,7 +38,7 @@ static struct powerdomain dsp_pwrdm = {
.pwrsts_mem_on= {
[0] = PWRSTS_ON,
},
-   .voltdm   = { .name = "core" },
+   .voltdm   = { .name = "core" },
 };
 
 static struct powerdomain mpu_24xx_pwrdm = {
@@ -53,7 +53,7 @@ static struct powerdomain mpu_24xx_pwrdm = {
.pwrsts_mem_on= {
[0] = PWRSTS_ON,
},
-   .voltdm   = { .name = "core" },
+   .voltdm   = { .name = "core" },
 };
 
 static struct powerdomain core_24xx_pwrdm = {
@@ -72,7 +72,7 @@ static struct powerdomain core_24xx_pwrdm = {
[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
[2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */
},
-   .voltdm   = { .name = "core" },
+   .voltdm   = { .name = "core" },
 };
 
 
@@ -94,7 +94,7 @@ static struct powerdomain mdm_pwrdm = {
.pwrsts_mem_on= {
[0] = PWRSTS_ON,  /* MEMONSTATE */
},
-   .voltdm   = { .name = "core" },
+   .voltdm   = { .name = "core" },
 };
 
 /*
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c 
b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index 8b23d23..f0e14e9ef 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -50,7 +50,7 @@ static struct powerdomain iva2_pwrdm = {
[2] = PWRSTS_OFF_ON,
[3] = PWRSTS_ON,
},
-   .voltdm   = { .name = "mpu_iva" },
+   .voltdm   = { .name = "mpu_iva" },
 };
 
 static struct powerdomain mpu_3xxx_pwrdm = {
@@ -66,7 +66,7 @@ static struct powerdomain mpu_3xxx_pwrdm = {
.pwrsts_mem_on= {

[PATCH 06/10] ARM: OMAP2+: powerdomain/clockdomain: add a per-powerdomain spinlock

2012-12-08 Thread Paul Walmsley
Add a per-powerdomain spinlock.  Use that instead of the clockdomain
spinlock.  Add pwrdm_lock()/pwrdm_unlock() functions to allow other
code to acquire or release the powerdomain spinlock without reaching
directly into the struct powerdomain.

Signed-off-by: Paul Walmsley 
Cc: Jean Pihet 
---
 arch/arm/mach-omap2/clockdomain-powerdomain.h |   22 +++
 arch/arm/mach-omap2/clockdomain.c |  161 +
 arch/arm/mach-omap2/clockdomain.h |6 +
 arch/arm/mach-omap2/powerdomain-clockdomain.h |   27 
 arch/arm/mach-omap2/powerdomain.c |   56 -
 arch/arm/mach-omap2/powerdomain.h |   11 +-
 6 files changed, 219 insertions(+), 64 deletions(-)
 create mode 100644 arch/arm/mach-omap2/clockdomain-powerdomain.h
 create mode 100644 arch/arm/mach-omap2/powerdomain-clockdomain.h

diff --git a/arch/arm/mach-omap2/clockdomain-powerdomain.h 
b/arch/arm/mach-omap2/clockdomain-powerdomain.h
new file mode 100644
index 000..8beee2d
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain-powerdomain.h
@@ -0,0 +1,22 @@
+/*
+ * OMAP clockdomain framework functions for use only by the powerdomain code
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_POWERDOMAIN_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_POWERDOMAIN_H
+
+#include "clockdomain.h"
+
+extern void clkdm_allow_idle_nolock(struct clockdomain *clkdm);
+extern void clkdm_deny_idle_nolock(struct clockdomain *clkdm);
+extern int clkdm_wakeup_nolock(struct clockdomain *clkdm);
+extern int clkdm_sleep_nolock(struct clockdomain *clkdm);
+
+#endif
diff --git a/arch/arm/mach-omap2/clockdomain.c 
b/arch/arm/mach-omap2/clockdomain.c
index 18f65fd..2142dab 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -30,6 +30,7 @@
 #include "soc.h"
 #include "clock.h"
 #include "clockdomain.h"
+#include "powerdomain-clockdomain.h"
 
 /* clkdm_list contains all registered struct clockdomains */
 static LIST_HEAD(clkdm_list);
@@ -91,8 +92,6 @@ static int _clkdm_register(struct clockdomain *clkdm)
 
pwrdm_add_clkdm(pwrdm, clkdm);
 
-   spin_lock_init(&clkdm->lock);
-
pr_debug("clockdomain: registered %s\n", clkdm->name);
 
return 0;
@@ -733,18 +732,17 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
 }
 
 /**
- * clkdm_sleep - force clockdomain sleep transition
+ * clkdm_sleep_nolock - force clockdomain sleep transition (lockless)
  * @clkdm: struct clockdomain *
  *
  * Instruct the CM to force a sleep transition on the specified
- * clockdomain @clkdm.  Returns -EINVAL if @clkdm is NULL or if
- * clockdomain does not support software-initiated sleep; 0 upon
- * success.
+ * clockdomain @clkdm.  Only for use by the powerdomain code.  Returns
+ * -EINVAL if @clkdm is NULL or if clockdomain does not support
+ * software-initiated sleep; 0 upon success.
  */
-int clkdm_sleep(struct clockdomain *clkdm)
+int clkdm_sleep_nolock(struct clockdomain *clkdm)
 {
int ret;
-   unsigned long flags;
 
if (!clkdm)
return -EINVAL;
@@ -760,27 +758,45 @@ int clkdm_sleep(struct clockdomain *clkdm)
 
pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
 
-   spin_lock_irqsave(&clkdm->lock, flags);
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
ret = arch_clkdm->clkdm_sleep(clkdm);
-   ret |= pwrdm_state_switch(clkdm->pwrdm.ptr);
-   spin_unlock_irqrestore(&clkdm->lock, flags);
+   ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
+
return ret;
 }
 
 /**
- * clkdm_wakeup - force clockdomain wakeup transition
+ * clkdm_sleep - force clockdomain sleep transition
  * @clkdm: struct clockdomain *
  *
- * Instruct the CM to force a wakeup transition on the specified
- * clockdomain @clkdm.  Returns -EINVAL if @clkdm is NULL or if the
- * clockdomain does not support software-controlled wakeup; 0 upon
+ * Instruct the CM to force a sleep transition on the specified
+ * clockdomain @clkdm.  Returns -EINVAL if @clkdm is NULL or if
+ * clockdomain does not support software-initiated sleep; 0 upon
  * success.
  */
-int clkdm_wakeup(struct clockdomain *clkdm)
+int clkdm_sleep(struct clockdomain *clkdm)
+{
+   int ret;
+
+   pwrdm_lock(clkdm->pwrdm.ptr);
+   ret = clkdm_sleep_nolock(clkdm);
+   pwrdm_unlock(clkdm->pwrdm.ptr);
+
+   return ret;
+}
+
+/**
+ * clkdm_wakeup_nolock - force clockdomain wakeup transition (lockless)
+ * @clkdm: struct clockdomain *
+ *
+ * Instruct the CM to force a wakeup transition on the specified
+ * clockdomain @clkdm.  Only for use by the powerdomain code.  Returns
+ * -EINVAL if @clkdm is NULL or if the clockdomain does not support
+ * software-controlled wakeup; 0 upon 

[PATCH 05/10] ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain code

2012-12-08 Thread Paul Walmsley
Move omap_set_pwrdm_state() from the PM code to the powerdomain code,
and refactor it to split it up into several functions.  A subsequent patch
will rename it to conform with the existing powerdomain function names.

Signed-off-by: Paul Walmsley 
Cc: Jean Pihet 
Cc: Kevin Hilman 
---
 arch/arm/mach-omap2/pm.c  |   61 
 arch/arm/mach-omap2/pm.h  |1 
 arch/arm/mach-omap2/powerdomain.c |  112 +++--
 arch/arm/mach-omap2/powerdomain.h |3 +
 4 files changed, 85 insertions(+), 92 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index cc8ed0f..2e2a897 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -76,10 +76,6 @@ static void __init omap2_init_processor_devices(void)
}
 }
 
-/* Types of sleep_switch used in omap_set_pwrdm_state */
-#define FORCEWAKEUP_SWITCH 0
-#define LOWPOWERSTATE_SWITCH   1
-
 int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
@@ -92,63 +88,6 @@ int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, 
void *unused)
 }
 
 /*
- * This sets pwrdm state (other than mpu & core. Currently only ON &
- * RET are supported.
- */
-int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
-{
-   u8 curr_pwrst, next_pwrst;
-   int sleep_switch = -1, ret = 0, hwsup = 0;
-
-   if (!pwrdm || IS_ERR(pwrdm))
-   return -EINVAL;
-
-   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;
-   }
-   }
-
-   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_state_switch(pwrdm);
-   break;
-   }
-
-   return ret;
-}
-
-
-
-/*
  * This API is to be called during init to set the various voltage
  * domains to the voltage as per the opp table. Typically we boot up
  * at the nominal voltage. So this function finds out the rate of
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 686137d..707e9cb 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -33,7 +33,6 @@ static inline int omap4_idle_init(void)
 extern void *omap3_secure_ram_storage;
 extern void omap3_pm_off_mode_enable(int);
 extern void omap_sram_idle(void);
-extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);
 extern int (*omap_pm_suspend)(void);
 
diff --git a/arch/arm/mach-omap2/powerdomain.c 
b/arch/arm/mach-omap2/powerdomain.c
index 97b3881..05f00660 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -921,35 +921,6 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
 }
 
-/**
- * pwrdm_set_lowpwrstchange - Request a low power state change
- * @pwrdm: struct powerdomain *
- *
- * Allows a powerdomain to transtion to a lower power sleep state
- * from an existing sleep state without waking up the powerdomain.
- * Returns -EINVAL if the powerdomain pointer is null or if the
- * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0
- * upon success.
- */
-int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
-{
-   int ret = -EINVAL;
-
-   if (!pwrdm)
-   return -EINVAL;
-
-   if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE))
-   return -EINVAL;
-
-   pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n",
-pwrdm->name);
-
-   if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange)
-   ret = arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
-
-   return ret;
-}
-
 int pwrdm_state_switch(struct powerdomain *pwrdm)
 {
int ret;
@@ -984,6 +955,8