Merge tag 'omap-fixes-a-for-3.10-rc' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-omap2 / omap_hwmod.c
index e3289888adfa003ba8aed3b244e803f98135e7e9..7341eff63f56df8f58d5b72d8db9a71feb86112d 100644 (file)
@@ -1356,13 +1356,27 @@ static void _enable_sysc(struct omap_hwmod *oh)
 
        clkdm = _get_clkdm(oh);
        if (sf & SYSC_HAS_SIDLEMODE) {
+               if (oh->flags & HWMOD_SWSUP_SIDLE ||
+                   oh->flags & HWMOD_SWSUP_SIDLE_ACT) {
+                       idlemode = HWMOD_IDLEMODE_NO;
+               } else {
+                       if (sf & SYSC_HAS_ENAWAKEUP)
+                               _enable_wakeup(oh, &v);
+                       if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+                               idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+                       else
+                               idlemode = HWMOD_IDLEMODE_SMART;
+               }
+
+               /*
+                * This is special handling for some IPs like
+                * 32k sync timer. Force them to idle!
+                */
                clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
                if (clkdm_act && !(oh->class->sysc->idlemodes &
                                   (SIDLE_SMART | SIDLE_SMART_WKUP)))
                        idlemode = HWMOD_IDLEMODE_FORCE;
-               else
-                       idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
-                               HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
+
                _set_slave_idlemode(oh, idlemode, &v);
        }
 
@@ -1391,10 +1405,6 @@ static void _enable_sysc(struct omap_hwmod *oh)
            (sf & SYSC_HAS_CLOCKACTIVITY))
                _set_clockactivity(oh, oh->class->sysc->clockact, &v);
 
-       /* If slave is in SMARTIDLE, also enable wakeup */
-       if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
-               _enable_wakeup(oh, &v);
-
        _write_sysconfig(v, oh);
 
        /*
@@ -1430,13 +1440,16 @@ static void _idle_sysc(struct omap_hwmod *oh)
        sf = oh->class->sysc->sysc_flags;
 
        if (sf & SYSC_HAS_SIDLEMODE) {
-               /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */
-               if (oh->flags & HWMOD_SWSUP_SIDLE ||
-                   !(oh->class->sysc->idlemodes &
-                     (SIDLE_SMART | SIDLE_SMART_WKUP)))
+               if (oh->flags & HWMOD_SWSUP_SIDLE) {
                        idlemode = HWMOD_IDLEMODE_FORCE;
-               else
-                       idlemode = HWMOD_IDLEMODE_SMART;
+               } else {
+                       if (sf & SYSC_HAS_ENAWAKEUP)
+                               _enable_wakeup(oh, &v);
+                       if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+                               idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+                       else
+                               idlemode = HWMOD_IDLEMODE_SMART;
+               }
                _set_slave_idlemode(oh, idlemode, &v);
        }
 
@@ -1455,10 +1468,6 @@ static void _idle_sysc(struct omap_hwmod *oh)
                _set_master_standbymode(oh, idlemode, &v);
        }
 
-       /* If slave is in SMARTIDLE, also enable wakeup */
-       if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
-               _enable_wakeup(oh, &v);
-
        _write_sysconfig(v, oh);
 }
 
@@ -2245,42 +2254,6 @@ static int _idle(struct omap_hwmod *oh)
        return 0;
 }
 
-/**
- * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit
- * @oh: struct omap_hwmod *
- * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
- *
- * Sets the IP block's OCP autoidle bit in hardware, and updates our
- * local copy. Intended to be used by drivers that require
- * direct manipulation of the AUTOIDLE bits.
- * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes
- * along the return value from _set_module_autoidle().
- *
- * Any users of this function should be scrutinized carefully.
- */
-int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle)
-{
-       u32 v;
-       int retval = 0;
-       unsigned long flags;
-
-       if (!oh || oh->_state != _HWMOD_STATE_ENABLED)
-               return -EINVAL;
-
-       spin_lock_irqsave(&oh->_lock, flags);
-
-       v = oh->_sysc_cache;
-
-       retval = _set_module_autoidle(oh, autoidle, &v);
-
-       if (!retval)
-               _write_sysconfig(v, oh);
-
-       spin_unlock_irqrestore(&oh->_lock, flags);
-
-       return retval;
-}
-
 /**
  * _shutdown - shutdown an omap_hwmod
  * @oh: struct omap_hwmod *
@@ -3179,38 +3152,6 @@ error:
        return ret;
 }
 
-/**
- * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode
- * @oh: struct omap_hwmod *
- * @idlemode: SIDLEMODE field bits (shifted to bit 0)
- *
- * Sets the IP block's OCP slave idlemode in hardware, and updates our
- * local copy.  Intended to be used by drivers that have some erratum
- * that requires direct manipulation of the SIDLEMODE bits.  Returns
- * -EINVAL if @oh is null, or passes along the return value from
- * _set_slave_idlemode().
- *
- * XXX Does this function have any current users?  If not, we should
- * remove it; it is better to let the rest of the hwmod code handle this.
- * Any users of this function should be scrutinized carefully.
- */
-int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
-{
-       u32 v;
-       int retval = 0;
-
-       if (!oh)
-               return -EINVAL;
-
-       v = oh->_sysc_cache;
-
-       retval = _set_slave_idlemode(oh, idlemode, &v);
-       if (!retval)
-               _write_sysconfig(v, oh);
-
-       return retval;
-}
-
 /**
  * omap_hwmod_lookup - look up a registered omap_hwmod by name
  * @name: name of the omap_hwmod to look up