aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c139
1 files changed, 83 insertions, 56 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6c6d31b432d2..bd9fc10ea737 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -781,39 +781,6 @@ static int _omap4_wait_target_disable(struct omap_hwmod *oh)
781} 781}
782 782
783/** 783/**
784 * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4
785 * @oh: struct omap_hwmod *
786 *
787 * Disable the PRCM module mode related to the hwmod @oh.
788 * Return EINVAL if the modulemode is not supported and 0 in case of success.
789 */
790static int _omap4_disable_module(struct omap_hwmod *oh)
791{
792 int v;
793
794 /* The module mode does not exist prior OMAP4 */
795 if (!cpu_is_omap44xx())
796 return -EINVAL;
797
798 if (!oh->clkdm || !oh->prcm.omap4.modulemode)
799 return -EINVAL;
800
801 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
802
803 omap4_cminst_module_disable(oh->clkdm->prcm_partition,
804 oh->clkdm->cm_inst,
805 oh->clkdm->clkdm_offs,
806 oh->prcm.omap4.clkctrl_offs);
807
808 v = _omap4_wait_target_disable(oh);
809 if (v)
810 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
811 oh->name);
812
813 return 0;
814}
815
816/**
817 * _count_mpu_irqs - count the number of MPU IRQ lines associated with @oh 784 * _count_mpu_irqs - count the number of MPU IRQ lines associated with @oh
818 * @oh: struct omap_hwmod *oh 785 * @oh: struct omap_hwmod *oh
819 * 786 *
@@ -1378,6 +1345,66 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)
1378} 1345}
1379 1346
1380/** 1347/**
1348 * _are_any_hardreset_lines_asserted - return true if part of @oh is hard-reset
1349 * @oh: struct omap_hwmod *
1350 *
1351 * If any hardreset line associated with @oh is asserted, then return true.
1352 * Otherwise, if @oh has no hardreset lines associated with it, or if
1353 * no hardreset lines associated with @oh are asserted, then return false.
1354 * This function is used to avoid executing some parts of the IP block
1355 * enable/disable sequence if a hardreset line is set.
1356 */
1357static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)
1358{
1359 int i;
1360
1361 if (oh->rst_lines_cnt == 0)
1362 return false;
1363
1364 for (i = 0; i < oh->rst_lines_cnt; i++)
1365 if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
1366 return true;
1367
1368 return false;
1369}
1370
1371/**
1372 * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4
1373 * @oh: struct omap_hwmod *
1374 *
1375 * Disable the PRCM module mode related to the hwmod @oh.
1376 * Return EINVAL if the modulemode is not supported and 0 in case of success.
1377 */
1378static int _omap4_disable_module(struct omap_hwmod *oh)
1379{
1380 int v;
1381
1382 /* The module mode does not exist prior OMAP4 */
1383 if (!cpu_is_omap44xx())
1384 return -EINVAL;
1385
1386 if (!oh->clkdm || !oh->prcm.omap4.modulemode)
1387 return -EINVAL;
1388
1389 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
1390
1391 omap4_cminst_module_disable(oh->clkdm->prcm_partition,
1392 oh->clkdm->cm_inst,
1393 oh->clkdm->clkdm_offs,
1394 oh->prcm.omap4.clkctrl_offs);
1395
1396 if (_are_any_hardreset_lines_asserted(oh))
1397 return 0;
1398
1399 v = _omap4_wait_target_disable(oh);
1400 if (v)
1401 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
1402 oh->name);
1403
1404 return 0;
1405}
1406
1407/**
1381 * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit 1408 * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit
1382 * @oh: struct omap_hwmod * 1409 * @oh: struct omap_hwmod *
1383 * 1410 *
@@ -1528,7 +1555,7 @@ static int _reset(struct omap_hwmod *oh)
1528 */ 1555 */
1529static int _enable(struct omap_hwmod *oh) 1556static int _enable(struct omap_hwmod *oh)
1530{ 1557{
1531 int r, i; 1558 int r;
1532 int hwsup = 0; 1559 int hwsup = 0;
1533 1560
1534 pr_debug("omap_hwmod: %s: enabling\n", oh->name); 1561 pr_debug("omap_hwmod: %s: enabling\n", oh->name);
@@ -1560,14 +1587,16 @@ static int _enable(struct omap_hwmod *oh)
1560 } 1587 }
1561 1588
1562 /* 1589 /*
1563 * If an IP contains HW reset lines, then de-assert them in order 1590 * If an IP block contains HW reset lines and any of them are
1564 * to allow the module state transition. Otherwise the PRCM will return 1591 * asserted, we let integration code associated with that
1565 * Intransition status, and the init will failed. 1592 * block handle the enable. We've received very little
1593 * information on what those driver authors need, and until
1594 * detailed information is provided and the driver code is
1595 * posted to the public lists, this is probably the best we
1596 * can do.
1566 */ 1597 */
1567 if (oh->_state == _HWMOD_STATE_INITIALIZED || 1598 if (_are_any_hardreset_lines_asserted(oh))
1568 oh->_state == _HWMOD_STATE_DISABLED) 1599 return 0;
1569 for (i = 0; i < oh->rst_lines_cnt; i++)
1570 _deassert_hardreset(oh, oh->rst_lines[i].name);
1571 1600
1572 /* Mux pins for device runtime if populated */ 1601 /* Mux pins for device runtime if populated */
1573 if (oh->mux && (!oh->mux->enabled || 1602 if (oh->mux && (!oh->mux->enabled ||
@@ -1642,6 +1671,9 @@ static int _idle(struct omap_hwmod *oh)
1642 return -EINVAL; 1671 return -EINVAL;
1643 } 1672 }
1644 1673
1674 if (_are_any_hardreset_lines_asserted(oh))
1675 return 0;
1676
1645 if (oh->class->sysc) 1677 if (oh->class->sysc)
1646 _idle_sysc(oh); 1678 _idle_sysc(oh);
1647 _del_initiator_dep(oh, mpu_oh); 1679 _del_initiator_dep(oh, mpu_oh);
@@ -1724,6 +1756,9 @@ static int _shutdown(struct omap_hwmod *oh)
1724 return -EINVAL; 1756 return -EINVAL;
1725 } 1757 }
1726 1758
1759 if (_are_any_hardreset_lines_asserted(oh))
1760 return 0;
1761
1727 pr_debug("omap_hwmod: %s: disabling\n", oh->name); 1762 pr_debug("omap_hwmod: %s: disabling\n", oh->name);
1728 1763
1729 if (oh->class->pre_shutdown) { 1764 if (oh->class->pre_shutdown) {
@@ -1866,21 +1901,13 @@ static int __init _setup_reset(struct omap_hwmod *oh)
1866 if (oh->_state != _HWMOD_STATE_INITIALIZED) 1901 if (oh->_state != _HWMOD_STATE_INITIALIZED)
1867 return -EINVAL; 1902 return -EINVAL;
1868 1903
1869 /* 1904 if (oh->rst_lines_cnt == 0) {
1870 * In the case of hwmod with hardreset that should not be 1905 r = _enable(oh);
1871 * de-assert at boot time, we have to keep the module 1906 if (r) {
1872 * initialized, because we cannot enable it properly with the 1907 pr_warning("omap_hwmod: %s: cannot be enabled for reset (%d)\n",
1873 * reset asserted. Exit without warning because that behavior 1908 oh->name, oh->_state);
1874 * is expected. 1909 return -EINVAL;
1875 */ 1910 }
1876 if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt > 0)
1877 return 0;
1878
1879 r = _enable(oh);
1880 if (r) {
1881 pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
1882 oh->name, oh->_state);
1883 return 0;
1884 } 1911 }
1885 1912
1886 if (!(oh->flags & HWMOD_INIT_NO_RESET)) 1913 if (!(oh->flags & HWMOD_INIT_NO_RESET))