From e9332b6eed82973a8f75f1f3d57babaa331d703c Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Mon, 8 Oct 2012 23:08:15 -0600 Subject: [PATCH] ARM: OMAP4/AM335x: hwmod: fix disable_module regression in hardreset handling Commit eb05f691290e99ee0bd1672317d6add789523c1e ("ARM: OMAP: hwmod: partially un-reset hwmods might not be properly enabled") added code to skip the IP block disable sequence if all of the block's hardreset lines weren't asserted. But this did not handle the case when no hardreset lines were associated with a module, which is the general case. In that situation, the IP block disable would be skipped. This is likely to cause PM regressions. So, modify _omap4_disable_module() and _am33xx_disable_module() to only bail out early if there are any hardreset lines asserted. And move the AM33xx test above the actual module disable code to ensure that the behavior is consistent. Reported-by: Archit Taneja Tested-by: Archit Taneja # DSS Cc: Omar Ramirez Luna Cc: Vaibhav Hiremath Acked-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath # AM335x Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 299ca2821ad1..b969ab1d258b 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1697,6 +1697,29 @@ static bool _are_all_hardreset_lines_asserted(struct omap_hwmod *oh) return false; } +/** + * _are_any_hardreset_lines_asserted - return true if any part of @oh is + * hard-reset + * @oh: struct omap_hwmod * + * + * If any hardreset lines associated with @oh are asserted, then + * return true. Otherwise, if no hardreset lines associated with @oh + * are asserted, or if @oh has no hardreset lines, then return false. + * This function is used to avoid executing some parts of the IP block + * enable/disable sequence if any hardreset line is set. + */ +static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh) +{ + int rst_cnt = 0; + int i; + + for (i = 0; i < oh->rst_lines_cnt && rst_cnt == 0; i++) + if (_read_hardreset(oh, oh->rst_lines[i].name) > 0) + rst_cnt++; + + return (rst_cnt) ? true : false; +} + /** * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4 * @oh: struct omap_hwmod * @@ -1715,7 +1738,7 @@ static int _omap4_disable_module(struct omap_hwmod *oh) * Since integration code might still be doing something, only * disable if all lines are under hardreset. */ - if (!_are_all_hardreset_lines_asserted(oh)) + if (_are_any_hardreset_lines_asserted(oh)) return 0; pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); @@ -1749,12 +1772,12 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); + if (_are_any_hardreset_lines_asserted(oh)) + return 0; + am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, oh->prcm.omap4.clkctrl_offs); - if (_are_all_hardreset_lines_asserted(oh)) - return 0; - v = _am33xx_wait_target_disable(oh); if (v) pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", -- 2.30.2