diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 49 | 
1 files changed, 36 insertions, 13 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 4653efb87a2..93f213b6a78 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -138,6 +138,9 @@  #include <linux/spinlock.h>  #include <linux/slab.h>  #include <linux/bootmem.h> +#include <linux/cpu.h> + +#include <asm/system_misc.h>  #include "clock.h"  #include "omap_hwmod.h" @@ -608,8 +611,6 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)  	/* XXX test pwrdm_get_wken for this hwmod's subsystem */ -	oh->_int_flags |= _HWMOD_WAKEUP_ENABLED; -  	return 0;  } @@ -643,8 +644,6 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)  	/* XXX test pwrdm_get_wken for this hwmod's subsystem */ -	oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED; -  	return 0;  } @@ -1366,7 +1365,9 @@ static void _enable_sysc(struct omap_hwmod *oh)  	}  	if (sf & SYSC_HAS_MIDLEMODE) { -		if (oh->flags & HWMOD_SWSUP_MSTANDBY) { +		if (oh->flags & HWMOD_FORCE_MSTANDBY) { +			idlemode = HWMOD_IDLEMODE_FORCE; +		} else if (oh->flags & HWMOD_SWSUP_MSTANDBY) {  			idlemode = HWMOD_IDLEMODE_NO;  		} else {  			if (sf & SYSC_HAS_ENAWAKEUP) @@ -1438,7 +1439,8 @@ static void _idle_sysc(struct omap_hwmod *oh)  	}  	if (sf & SYSC_HAS_MIDLEMODE) { -		if (oh->flags & HWMOD_SWSUP_MSTANDBY) { +		if ((oh->flags & HWMOD_SWSUP_MSTANDBY) || +		    (oh->flags & HWMOD_FORCE_MSTANDBY)) {  			idlemode = HWMOD_IDLEMODE_FORCE;  		} else {  			if (sf & SYSC_HAS_ENAWAKEUP) @@ -1661,7 +1663,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)  		return -ENOSYS;  	ret = _lookup_hardreset(oh, name, &ohri); -	if (IS_ERR_VALUE(ret)) +	if (ret < 0)  		return ret;  	if (oh->clkdm) { @@ -2053,6 +2055,23 @@ static int _omap4_get_context_lost(struct omap_hwmod *oh)  }  /** + * _enable_preprogram - Pre-program an IP block during the _enable() process + * @oh: struct omap_hwmod * + * + * Some IP blocks (such as AESS) require some additional programming + * after enable before they can enter idle.  If a function pointer to + * do so is present in the hwmod data, then call it and pass along the + * return value; otherwise, return 0. + */ +static int __init _enable_preprogram(struct omap_hwmod *oh) +{ +	if (!oh->class->enable_preprogram) +		return 0; + +	return oh->class->enable_preprogram(oh); +} + +/**   * _enable - enable an omap_hwmod   * @oh: struct omap_hwmod *   * @@ -2134,6 +2153,8 @@ static int _enable(struct omap_hwmod *oh)  	_enable_clocks(oh);  	if (soc_ops.enable_module)  		soc_ops.enable_module(oh); +	if (oh->flags & HWMOD_BLOCK_WFI) +		cpu_idle_poll_ctrl(true);  	if (soc_ops.update_context_lost)  		soc_ops.update_context_lost(oh); @@ -2156,6 +2177,7 @@ static int _enable(struct omap_hwmod *oh)  				_update_sysc_cache(oh);  			_enable_sysc(oh);  		} +		r = _enable_preprogram(oh);  	} else {  		if (soc_ops.disable_module)  			soc_ops.disable_module(oh); @@ -2195,6 +2217,8 @@ static int _idle(struct omap_hwmod *oh)  		_idle_sysc(oh);  	_del_initiator_dep(oh, mpu_oh); +	if (oh->flags & HWMOD_BLOCK_WFI) +		cpu_idle_poll_ctrl(false);  	if (soc_ops.disable_module)  		soc_ops.disable_module(oh); @@ -2303,6 +2327,8 @@ static int _shutdown(struct omap_hwmod *oh)  	if (oh->_state == _HWMOD_STATE_ENABLED) {  		_del_initiator_dep(oh, mpu_oh);  		/* XXX what about the other system initiators here? dma, dsp */ +		if (oh->flags & HWMOD_BLOCK_WFI) +			cpu_idle_poll_ctrl(false);  		if (soc_ops.disable_module)  			soc_ops.disable_module(oh);  		_disable_clocks(oh); @@ -2387,7 +2413,7 @@ static int __init _init(struct omap_hwmod *oh, void *data)  	_init_mpu_rt_base(oh, NULL);  	r = _init_clocks(oh, NULL); -	if (IS_ERR_VALUE(r)) { +	if (r < 0) {  		WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);  		return -EINVAL;  	} @@ -3041,11 +3067,8 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh,  static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,  				     struct omap_hwmod_rst_info *ohri)  { -	if (ohri->st_shift) -		pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", -		       oh->name, ohri->name); -  	return am33xx_prm_deassert_hardreset(ohri->rst_shift, +				ohri->st_shift,  				oh->clkdm->pwrdm.ptr->prcm_offs,  				oh->prcm.omap4.rstctrl_offs,  				oh->prcm.omap4.rstst_offs); @@ -3303,7 +3326,7 @@ static int __init omap_hwmod_setup_all(void)  	return 0;  } -core_initcall(omap_hwmod_setup_all); +omap_core_initcall(omap_hwmod_setup_all);  /**   * omap_hwmod_enable - enable an omap_hwmod  |