aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2012-10-09 01:08:15 -0400
committerPaul Walmsley <paul@pwsan.com>2012-10-09 01:08:15 -0400
commite9332b6eed82973a8f75f1f3d57babaa331d703c (patch)
treebeb9158583964f44fcbd0879ad9394fb5dd8c55c /arch/arm/mach-omap2/omap_hwmod.c
parentcf956d9f0734b4888655d6b7420e4dac9dba22d0 (diff)
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 <a0393947@ti.com> Tested-by: Archit Taneja <a0393947@ti.com> # DSS Cc: Omar Ramirez Luna <omar.luna@linaro.org> Cc: Vaibhav Hiremath <hvaibhav@ti.com> Acked-by: Vaibhav Hiremath <hvaibhav@ti.com> Tested-by: Vaibhav Hiremath <hvaibhav@ti.com> # AM335x 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.c31
1 files 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
@@ -1698,6 +1698,29 @@ static bool _are_all_hardreset_lines_asserted(struct omap_hwmod *oh)
1698} 1698}
1699 1699
1700/** 1700/**
1701 * _are_any_hardreset_lines_asserted - return true if any part of @oh is
1702 * hard-reset
1703 * @oh: struct omap_hwmod *
1704 *
1705 * If any hardreset lines associated with @oh are asserted, then
1706 * return true. Otherwise, if no hardreset lines associated with @oh
1707 * are asserted, or if @oh has no hardreset lines, then return false.
1708 * This function is used to avoid executing some parts of the IP block
1709 * enable/disable sequence if any hardreset line is set.
1710 */
1711static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)
1712{
1713 int rst_cnt = 0;
1714 int i;
1715
1716 for (i = 0; i < oh->rst_lines_cnt && rst_cnt == 0; i++)
1717 if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
1718 rst_cnt++;
1719
1720 return (rst_cnt) ? true : false;
1721}
1722
1723/**
1701 * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4 1724 * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4
1702 * @oh: struct omap_hwmod * 1725 * @oh: struct omap_hwmod *
1703 * 1726 *
@@ -1715,7 +1738,7 @@ static int _omap4_disable_module(struct omap_hwmod *oh)
1715 * Since integration code might still be doing something, only 1738 * Since integration code might still be doing something, only
1716 * disable if all lines are under hardreset. 1739 * disable if all lines are under hardreset.
1717 */ 1740 */
1718 if (!_are_all_hardreset_lines_asserted(oh)) 1741 if (_are_any_hardreset_lines_asserted(oh))
1719 return 0; 1742 return 0;
1720 1743
1721 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); 1744 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
@@ -1749,12 +1772,12 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)
1749 1772
1750 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); 1773 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
1751 1774
1775 if (_are_any_hardreset_lines_asserted(oh))
1776 return 0;
1777
1752 am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, 1778 am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs,
1753 oh->prcm.omap4.clkctrl_offs); 1779 oh->prcm.omap4.clkctrl_offs);
1754 1780
1755 if (_are_all_hardreset_lines_asserted(oh))
1756 return 0;
1757
1758 v = _am33xx_wait_target_disable(oh); 1781 v = _am33xx_wait_target_disable(oh);
1759 if (v) 1782 if (v)
1760 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", 1783 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",