Merge tag 'omap-cleanup-b-for-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorTony Lindgren <tony@atomide.com>
Wed, 30 Jan 2013 22:03:05 +0000 (14:03 -0800)
committerTony Lindgren <tony@atomide.com>
Wed, 30 Jan 2013 22:03:05 +0000 (14:03 -0800)
Several OMAP2+ power management fixes, optimizations, and cleanup.
This series is a prerequisite for the functional powerdomain
conversion series.

Basic test logs for this branch are here:

    http://www.pwsan.com/omap/testlogs/pm_cleanup_fixes_3.9/20130129150017/

1  2 
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/pm24xx.c

diff --combined arch/arm/mach-omap2/pm.c
@@@ -32,6 -32,8 +32,6 @@@
  #include "pm.h"
  #include "twl-common.h"
  
 -static struct omap_device_pm_latency *pm_lats;
 -
  /*
   * omap_pm_suspend: points to a function that does the SoC-specific
   * suspend work
@@@ -80,7 -82,7 +80,7 @@@ static int __init _init_omap_device(cha
                 __func__, name))
                return -ENODEV;
  
 -      pdev = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false);
 +      pdev = omap_device_build(oh->name, 0, oh, NULL, 0);
        if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n",
                 __func__, name))
                return -ENODEV;
@@@ -106,80 -108,19 +106,19 @@@ static void __init omap2_init_processor
        }
  }
  
- /* 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)
  {
+       /* XXX The usecount test is racy */
        if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
            !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
                clkdm_allow_idle(clkdm);
        else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
-                atomic_read(&clkdm->usecount) == 0)
+                clkdm->usecount == 0)
                clkdm_sleep(clkdm);
        return 0;
  }
  
  /*
-  * 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_wait_transition(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
@@@ -90,11 -90,7 +90,7 @@@ static int omap2_enter_full_retention(v
        omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
        omap2_prm_write_mod_reg(0xffffffff, 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 */
@@@ -137,9 -133,20 +133,12 @@@ 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;
  }
  
 -static int omap2_i2c_active(void)
 -{
 -      u32 l;
 -
 -      l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
 -      return l & (OMAP2420_EN_I2C2_MASK | OMAP2420_EN_I2C1_MASK);
 -}
 -
  static int sti_console_enabled;
  
  static int omap2_allow_mpu_retention(void)
  
  static void omap2_enter_mpu_retention(void)
  {
 -      /* Putting MPU into the WFI state while a transfer is active
 -       * seems to cause the I2C block to timeout. Why? Good question. */
 -      if (omap2_i2c_active())
 -              return;
 -
        /* The peripherals seem not to be able to wake up the MPU when
         * it is in retention mode. */
        if (omap2_allow_mpu_retention()) {
                omap2_prm_write_mod_reg(0xffffffff, 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)
@@@ -238,25 -249,17 +236,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);