diff options
| author | Benoit Cousson <b-cousson@ti.com> | 2011-07-01 22:54:00 +0200 | 
|---|---|---|
| committer | Paul Walmsley <paul@pwsan.com> | 2011-07-09 19:13:35 -0600 | 
| commit | 724019b0137acf2ea43e5ca854798851f5ebf51f (patch) | |
| tree | 7868806c219b4e31507f998cde481ad8add42888 /arch/arm/mach-omap2/omap_hwmod.c | |
| parent | ecba3287b4121dcf3ca7607fe71c205913edec06 (diff) | |
| download | olio-linux-3.10-724019b0137acf2ea43e5ca854798851f5ebf51f.tar.xz olio-linux-3.10-724019b0137acf2ea43e5ca854798851f5ebf51f.zip  | |
OMAP2+: hwmod: Fix smart-standby + wakeup support
The commit 86009eb326afde34ffdc5648cd344aa86b8d58d4 was adding
the wakeup support for new OMAP4 IPs. This support is incomplete for
busmaster IPs that need as well to use smart-standby with wakeup.
This new standbymode is suported on HSI and USB_HOST_FS for the moment.
Add the new MSTANDBY_SMART_WKUP flag to mark the IPs that support this
capability.
Enable this new mode when applicable in _enable_wakeup, _disable_wakeup,
_enable_sysc and _idle_sysc.
The omap_hwmod_44xx_data.c will have to be updated to add this new flag.
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
Signed-off-by: Djamil Elaidi <d-elaidi@ti.com>
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 34 | 
1 files changed, 28 insertions, 6 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 293fa6cd50e..384d3c3ec36 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -391,7 +391,8 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)  	if (!oh->class->sysc ||  	    !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) || -	      (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP))) +	      (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) || +	      (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))  		return -EINVAL;  	if (!oh->class->sysc->sysc_fields) { @@ -405,6 +406,8 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)  	if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)  		_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v); +	if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) +		_set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);  	/* XXX test pwrdm_get_wken for this hwmod's subsystem */ @@ -426,7 +429,8 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)  	if (!oh->class->sysc ||  	    !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) || -	      (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP))) +	      (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) || +	      (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))  		return -EINVAL;  	if (!oh->class->sysc->sysc_fields) { @@ -440,6 +444,8 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)  	if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)  		_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v); +	if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) +		_set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);  	/* XXX test pwrdm_get_wken for this hwmod's subsystem */ @@ -781,8 +787,16 @@ static void _enable_sysc(struct omap_hwmod *oh)  	}  	if (sf & SYSC_HAS_MIDLEMODE) { -		idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ? -			HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; +		if (oh->flags & HWMOD_SWSUP_MSTANDBY) { +			idlemode = HWMOD_IDLEMODE_NO; +		} else { +			if (sf & SYSC_HAS_ENAWAKEUP) +				_enable_wakeup(oh, &v); +			if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) +				idlemode = HWMOD_IDLEMODE_SMART_WKUP; +			else +				idlemode = HWMOD_IDLEMODE_SMART; +		}  		_set_master_standbymode(oh, idlemode, &v);  	} @@ -840,8 +854,16 @@ static void _idle_sysc(struct omap_hwmod *oh)  	}  	if (sf & SYSC_HAS_MIDLEMODE) { -		idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ? -			HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; +		if (oh->flags & HWMOD_SWSUP_MSTANDBY) { +			idlemode = HWMOD_IDLEMODE_FORCE; +		} else { +			if (sf & SYSC_HAS_ENAWAKEUP) +				_enable_wakeup(oh, &v); +			if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) +				idlemode = HWMOD_IDLEMODE_SMART_WKUP; +			else +				idlemode = HWMOD_IDLEMODE_SMART; +		}  		_set_master_standbymode(oh, idlemode, &v);  	}  |