aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
authorOmar Ramirez Luna <omar.luna@linaro.org>2012-09-23 19:28:20 -0400
committerPaul Walmsley <paul@pwsan.com>2012-09-23 19:28:20 -0400
commiteb05f691290e99ee0bd1672317d6add789523c1e (patch)
tree1df79aa4c0faddd49c10afb81e4dc20bab2c5b7b /arch/arm/mach-omap2/omap_hwmod.c
parent46b3af27894a3b414712bef313c4aacb605fccf7 (diff)
ARM: OMAP: hwmod: partially un-reset hwmods might not be properly enabled
Some IP blocks might not be using/controlling more than one reset line, this check loosens the restriction to fully use hwmod framework for those drivers. E.g.: ipu has reset lines: mmu_cache, cpu0 and cpu1. - As of now cpu1 is not used and hence (with previous check) the IP block isn't fully enabled by hwmod code. - Usually ipu and dsp processors configure their mmu module first and then enable the processors, this involves: * Deasserting mmu reset line, and enabling the module. * Deasserting cpu0 reset line, and enabling the processor. The ones portrayed in this example are controlled through rproc_fw_boot in drivers/remoteproc/remoteproc_core.c While at it, prevent _omap4_module_disable if all the hardreset lines on an IP block are not under reset. This will allow the driver to: a. Deassert the reset line. b. Enable the hwmod through runtime PM default callbacks. c. Do its usecase. d. Disable hwmod through runtime PM. e. Assert the reset line. Signed-off-by: Omar Ramirez Luna <omar.luna@linaro.org> [paul@pwsan.com: updated to apply] 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.c39
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 4f6b50f220c5..8d933528b708 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)
1634} 1634}
1635 1635
1636/** 1636/**
1637 * _are_any_hardreset_lines_asserted - return true if part of @oh is hard-reset 1637 * _are_all_hardreset_lines_asserted - return true if the @oh is hard-reset
1638 * @oh: struct omap_hwmod * 1638 * @oh: struct omap_hwmod *
1639 * 1639 *
1640 * If any hardreset line associated with @oh is asserted, then return true. 1640 * If all hardreset lines associated with @oh are asserted, then return true.
1641 * Otherwise, if @oh has no hardreset lines associated with it, or if 1641 * Otherwise, if part of @oh is out hardreset or if no hardreset lines
1642 * no hardreset lines associated with @oh are asserted, then return false. 1642 * associated with @oh are asserted, then return false.
1643 * This function is used to avoid executing some parts of the IP block 1643 * This function is used to avoid executing some parts of the IP block
1644 * enable/disable sequence if a hardreset line is set. 1644 * enable/disable sequence if its hardreset line is set.
1645 */ 1645 */
1646static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh) 1646static bool _are_all_hardreset_lines_asserted(struct omap_hwmod *oh)
1647{ 1647{
1648 int i; 1648 int i, rst_cnt = 0;
1649 1649
1650 if (oh->rst_lines_cnt == 0) 1650 if (oh->rst_lines_cnt == 0)
1651 return false; 1651 return false;
1652 1652
1653 for (i = 0; i < oh->rst_lines_cnt; i++) 1653 for (i = 0; i < oh->rst_lines_cnt; i++)
1654 if (_read_hardreset(oh, oh->rst_lines[i].name) > 0) 1654 if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
1655 return true; 1655 rst_cnt++;
1656
1657 if (oh->rst_lines_cnt == rst_cnt)
1658 return true;
1656 1659
1657 return false; 1660 return false;
1658} 1661}
@@ -1671,6 +1674,13 @@ static int _omap4_disable_module(struct omap_hwmod *oh)
1671 if (!oh->clkdm || !oh->prcm.omap4.modulemode) 1674 if (!oh->clkdm || !oh->prcm.omap4.modulemode)
1672 return -EINVAL; 1675 return -EINVAL;
1673 1676
1677 /*
1678 * Since integration code might still be doing something, only
1679 * disable if all lines are under hardreset.
1680 */
1681 if (!_are_all_hardreset_lines_asserted(oh))
1682 return 0;
1683
1674 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); 1684 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
1675 1685
1676 omap4_cminst_module_disable(oh->clkdm->prcm_partition, 1686 omap4_cminst_module_disable(oh->clkdm->prcm_partition,
@@ -1678,9 +1688,6 @@ static int _omap4_disable_module(struct omap_hwmod *oh)
1678 oh->clkdm->clkdm_offs, 1688 oh->clkdm->clkdm_offs,
1679 oh->prcm.omap4.clkctrl_offs); 1689 oh->prcm.omap4.clkctrl_offs);
1680 1690
1681 if (_are_any_hardreset_lines_asserted(oh))
1682 return 0;
1683
1684 v = _omap4_wait_target_disable(oh); 1691 v = _omap4_wait_target_disable(oh);
1685 if (v) 1692 if (v)
1686 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", 1693 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
@@ -1708,7 +1715,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)
1708 am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, 1715 am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs,
1709 oh->prcm.omap4.clkctrl_offs); 1716 oh->prcm.omap4.clkctrl_offs);
1710 1717
1711 if (_are_any_hardreset_lines_asserted(oh)) 1718 if (_are_all_hardreset_lines_asserted(oh))
1712 return 0; 1719 return 0;
1713 1720
1714 v = _am33xx_wait_target_disable(oh); 1721 v = _am33xx_wait_target_disable(oh);
@@ -1936,7 +1943,7 @@ static int _enable(struct omap_hwmod *oh)
1936 } 1943 }
1937 1944
1938 /* 1945 /*
1939 * If an IP block contains HW reset lines and any of them are 1946 * If an IP block contains HW reset lines and all of them are
1940 * asserted, we let integration code associated with that 1947 * asserted, we let integration code associated with that
1941 * block handle the enable. We've received very little 1948 * block handle the enable. We've received very little
1942 * information on what those driver authors need, and until 1949 * information on what those driver authors need, and until
@@ -1944,7 +1951,7 @@ static int _enable(struct omap_hwmod *oh)
1944 * posted to the public lists, this is probably the best we 1951 * posted to the public lists, this is probably the best we
1945 * can do. 1952 * can do.
1946 */ 1953 */
1947 if (_are_any_hardreset_lines_asserted(oh)) 1954 if (_are_all_hardreset_lines_asserted(oh))
1948 return 0; 1955 return 0;
1949 1956
1950 /* Mux pins for device runtime if populated */ 1957 /* Mux pins for device runtime if populated */
@@ -2025,7 +2032,7 @@ static int _idle(struct omap_hwmod *oh)
2025 return -EINVAL; 2032 return -EINVAL;
2026 } 2033 }
2027 2034
2028 if (_are_any_hardreset_lines_asserted(oh)) 2035 if (_are_all_hardreset_lines_asserted(oh))
2029 return 0; 2036 return 0;
2030 2037
2031 if (oh->class->sysc) 2038 if (oh->class->sysc)
@@ -2113,7 +2120,7 @@ static int _shutdown(struct omap_hwmod *oh)
2113 return -EINVAL; 2120 return -EINVAL;
2114 } 2121 }
2115 2122
2116 if (_are_any_hardreset_lines_asserted(oh)) 2123 if (_are_all_hardreset_lines_asserted(oh))
2117 return 0; 2124 return 0;
2118 2125
2119 pr_debug("omap_hwmod: %s: disabling\n", oh->name); 2126 pr_debug("omap_hwmod: %s: disabling\n", oh->name);