Current implementation of the hw_mod sysconfig configuration
always sets up SMART idle mode for HW modules. However, a certain
HW module may not support smart idle mode or may have
HW bugs that prevent using smart idle mode.

This patch introduces a mechanism to check supported
idle modes and select in following priority:
1. Smart idle mode
2. Force idle mode
3. No idle mode.

Signed-off-by: Kalle Jokiniemi <kalle.jokini...@nokia.com>
---
 arch/arm/mach-omap2/omap_hwmod.c |   28 ++++++++++++++++++++--------
 1 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 028efda..ef77697 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -757,7 +757,7 @@ static void __iomem * __init _find_mpu_rt_base(struct 
omap_hwmod *oh, u8 index)
  */
 static void _enable_sysc(struct omap_hwmod *oh)
 {
-       u8 idlemode, sf;
+       u8 idlemode, sf, idlemode_flags;
        u32 v;
 
        if (!oh->class->sysc)
@@ -765,17 +765,28 @@ static void _enable_sysc(struct omap_hwmod *oh)
 
        v = oh->_sysc_cache;
        sf = oh->class->sysc->sysc_flags;
+       idlemode_flags = oh->class->sysc->idlemodes;
+
+       /* Set the idlemode, priority order: 1. SMART 2. FORCE 3. NOIDLE */
+       if (idlemode_flags & SIDLE_SMART)
+               idlemode = HWMOD_IDLEMODE_SMART;
+       else if (idlemode_flags & SIDLE_FORCE)
+               idlemode = HWMOD_IDLEMODE_FORCE;
+       else
+               idlemode = HWMOD_IDLEMODE_NO;
 
        if (sf & SYSC_HAS_SIDLEMODE) {
-               idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
-                       HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
-               _set_slave_idlemode(oh, idlemode, &v);
+               if (oh->flags & HWMOD_SWSUP_SIDLE)
+                       _set_slave_idlemode(oh, HWMOD_IDLEMODE_NO, &v);
+               else
+                       _set_slave_idlemode(oh, idlemode, &v);
        }
 
        if (sf & SYSC_HAS_MIDLEMODE) {
-               idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
-                       HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
-               _set_master_standbymode(oh, idlemode, &v);
+               if (oh->flags & HWMOD_SWSUP_MSTANDBY)
+                       _set_master_standbymode(oh, HWMOD_IDLEMODE_NO, &v);
+               else
+                       _set_master_standbymode(oh, idlemode, &v);
        }
 
        /*
@@ -788,7 +799,8 @@ static void _enable_sysc(struct omap_hwmod *oh)
                _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))
+       if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE) &&
+                       idlemode_flags & SIDLE_SMART)
                _enable_wakeup(oh, &v);
 
        _write_sysconfig(v, oh);
-- 
1.7.1

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

Reply via email to