diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 55 | 
1 files changed, 51 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 68616b2b5b9..083adbed0bf 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -187,6 +187,8 @@ struct omap_hwmod_soc_ops {  	int (*is_hardreset_asserted)(struct omap_hwmod *oh,  				     struct omap_hwmod_rst_info *ohri);  	int (*init_clkdm)(struct omap_hwmod *oh); +	void (*update_context_lost)(struct omap_hwmod *oh); +	int (*get_context_lost)(struct omap_hwmod *oh);  };  /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ @@ -1983,6 +1985,42 @@ static void _reconfigure_io_chain(void)  }  /** + * _omap4_update_context_lost - increment hwmod context loss counter if + * hwmod context was lost, and clear hardware context loss reg + * @oh: hwmod to check for context loss + * + * If the PRCM indicates that the hwmod @oh lost context, increment + * our in-memory context loss counter, and clear the RM_*_CONTEXT + * bits. No return value. + */ +static void _omap4_update_context_lost(struct omap_hwmod *oh) +{ +	if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT) +		return; + +	if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition, +					  oh->clkdm->pwrdm.ptr->prcm_offs, +					  oh->prcm.omap4.context_offs)) +		return; + +	oh->prcm.omap4.context_lost_counter++; +	prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition, +					 oh->clkdm->pwrdm.ptr->prcm_offs, +					 oh->prcm.omap4.context_offs); +} + +/** + * _omap4_get_context_lost - get context loss counter for a hwmod + * @oh: hwmod to get context loss counter for + * + * Returns the in-memory context loss counter for a hwmod. + */ +static int _omap4_get_context_lost(struct omap_hwmod *oh) +{ +	return oh->prcm.omap4.context_lost_counter; +} + +/**   * _enable - enable an omap_hwmod   * @oh: struct omap_hwmod *   * @@ -2065,6 +2103,9 @@ static int _enable(struct omap_hwmod *oh)  	if (soc_ops.enable_module)  		soc_ops.enable_module(oh); +	if (soc_ops.update_context_lost) +		soc_ops.update_context_lost(oh); +  	r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :  		-EINVAL;  	if (!r) { @@ -3907,17 +3948,21 @@ ohsps_unlock:   * omap_hwmod_get_context_loss_count - get lost context count   * @oh: struct omap_hwmod *   * - * Query the powerdomain of of @oh to get the context loss - * count for this device. + * Returns the context loss count of associated @oh + * upon success, or zero if no context loss data is available.   * - * Returns the context loss count of the powerdomain assocated with @oh - * upon success, or zero if no powerdomain exists for @oh. + * On OMAP4, this queries the per-hwmod context loss register, + * assuming one exists.  If not, or on OMAP2/3, this queries the + * enclosing powerdomain context loss count.   */  int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)  {  	struct powerdomain *pwrdm;  	int ret = 0; +	if (soc_ops.get_context_lost) +		return soc_ops.get_context_lost(oh); +  	pwrdm = omap_hwmod_get_pwrdm(oh);  	if (pwrdm)  		ret = pwrdm_get_context_loss_count(pwrdm); @@ -4032,6 +4077,8 @@ void __init omap_hwmod_init(void)  		soc_ops.deassert_hardreset = _omap4_deassert_hardreset;  		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;  		soc_ops.init_clkdm = _init_clkdm; +		soc_ops.update_context_lost = _omap4_update_context_lost; +		soc_ops.get_context_lost = _omap4_get_context_lost;  	} else if (soc_is_am33xx()) {  		soc_ops.enable_module = _am33xx_enable_module;  		soc_ops.disable_module = _am33xx_disable_module;  |