diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 39 | 
1 files changed, 23 insertions, 16 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 4f6b50f220c..8d933528b70 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1634,25 +1634,28 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)  }  /** - * _are_any_hardreset_lines_asserted - return true if part of @oh is hard-reset + * _are_all_hardreset_lines_asserted - return true if the @oh is hard-reset   * @oh: struct omap_hwmod *   * - * If any hardreset line associated with @oh is asserted, then return true. - * Otherwise, if @oh has no hardreset lines associated with it, or if - * no hardreset lines associated with @oh are asserted, then return false. + * If all hardreset lines associated with @oh are asserted, then return true. + * Otherwise, if part of @oh is out hardreset or if no hardreset lines + * associated with @oh are asserted, then return false.   * This function is used to avoid executing some parts of the IP block - * enable/disable sequence if a hardreset line is set. + * enable/disable sequence if its hardreset line is set.   */ -static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh) +static bool _are_all_hardreset_lines_asserted(struct omap_hwmod *oh)  { -	int i; +	int i, rst_cnt = 0;  	if (oh->rst_lines_cnt == 0)  		return false;  	for (i = 0; i < oh->rst_lines_cnt; i++)  		if (_read_hardreset(oh, oh->rst_lines[i].name) > 0) -			return true; +			rst_cnt++; + +	if (oh->rst_lines_cnt == rst_cnt) +		return true;  	return false;  } @@ -1671,6 +1674,13 @@ static int _omap4_disable_module(struct omap_hwmod *oh)  	if (!oh->clkdm || !oh->prcm.omap4.modulemode)  		return -EINVAL; +	/* +	 * Since integration code might still be doing something, only +	 * disable if all lines are under hardreset. +	 */ +	if (!_are_all_hardreset_lines_asserted(oh)) +		return 0; +  	pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);  	omap4_cminst_module_disable(oh->clkdm->prcm_partition, @@ -1678,9 +1688,6 @@ static int _omap4_disable_module(struct omap_hwmod *oh)  				    oh->clkdm->clkdm_offs,  				    oh->prcm.omap4.clkctrl_offs); -	if (_are_any_hardreset_lines_asserted(oh)) -		return 0; -  	v = _omap4_wait_target_disable(oh);  	if (v)  		pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", @@ -1708,7 +1715,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)  	am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs,  				 oh->prcm.omap4.clkctrl_offs); -	if (_are_any_hardreset_lines_asserted(oh)) +	if (_are_all_hardreset_lines_asserted(oh))  		return 0;  	v = _am33xx_wait_target_disable(oh); @@ -1936,7 +1943,7 @@ static int _enable(struct omap_hwmod *oh)  	}  	/* -	 * If an IP block contains HW reset lines and any of them are +	 * If an IP block contains HW reset lines and all of them are  	 * asserted, we let integration code associated with that  	 * block handle the enable.  We've received very little  	 * information on what those driver authors need, and until @@ -1944,7 +1951,7 @@ static int _enable(struct omap_hwmod *oh)  	 * posted to the public lists, this is probably the best we  	 * can do.  	 */ -	if (_are_any_hardreset_lines_asserted(oh)) +	if (_are_all_hardreset_lines_asserted(oh))  		return 0;  	/* Mux pins for device runtime if populated */ @@ -2025,7 +2032,7 @@ static int _idle(struct omap_hwmod *oh)  		return -EINVAL;  	} -	if (_are_any_hardreset_lines_asserted(oh)) +	if (_are_all_hardreset_lines_asserted(oh))  		return 0;  	if (oh->class->sysc) @@ -2113,7 +2120,7 @@ static int _shutdown(struct omap_hwmod *oh)  		return -EINVAL;  	} -	if (_are_any_hardreset_lines_asserted(oh)) +	if (_are_all_hardreset_lines_asserted(oh))  		return 0;  	pr_debug("omap_hwmod: %s: disabling\n", oh->name);  |