|
@@ -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
|