diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 248 |
1 files changed, 193 insertions, 55 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index e282e35769fd..e39772beaedd 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * omap_hwmod implementation for OMAP2/3/4 | 2 | * omap_hwmod implementation for OMAP2/3/4 |
3 | * | 3 | * |
4 | * Copyright (C) 2009-2010 Nokia Corporation | 4 | * Copyright (C) 2009-2011 Nokia Corporation |
5 | * | 5 | * |
6 | * Paul Walmsley, Benoît Cousson, Kevin Hilman | 6 | * Paul Walmsley, Benoît Cousson, Kevin Hilman |
7 | * | 7 | * |
@@ -162,9 +162,6 @@ static LIST_HEAD(omap_hwmod_list); | |||
162 | /* mpu_oh: used to add/remove MPU initiator from sleepdep list */ | 162 | /* mpu_oh: used to add/remove MPU initiator from sleepdep list */ |
163 | static struct omap_hwmod *mpu_oh; | 163 | static struct omap_hwmod *mpu_oh; |
164 | 164 | ||
165 | /* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */ | ||
166 | static u8 inited; | ||
167 | |||
168 | 165 | ||
169 | /* Private functions */ | 166 | /* Private functions */ |
170 | 167 | ||
@@ -460,14 +457,18 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v) | |||
460 | * will be accessed by a particular initiator (e.g., if a module will | 457 | * will be accessed by a particular initiator (e.g., if a module will |
461 | * be accessed by the IVA, there should be a sleepdep between the IVA | 458 | * be accessed by the IVA, there should be a sleepdep between the IVA |
462 | * initiator and the module). Only applies to modules in smart-idle | 459 | * initiator and the module). Only applies to modules in smart-idle |
463 | * mode. Returns -EINVAL upon error or passes along | 460 | * mode. If the clockdomain is marked as not needing autodeps, return |
464 | * clkdm_add_sleepdep() value upon success. | 461 | * 0 without doing anything. Otherwise, returns -EINVAL upon error or |
462 | * passes along clkdm_add_sleepdep() value upon success. | ||
465 | */ | 463 | */ |
466 | static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) | 464 | static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) |
467 | { | 465 | { |
468 | if (!oh->_clk) | 466 | if (!oh->_clk) |
469 | return -EINVAL; | 467 | return -EINVAL; |
470 | 468 | ||
469 | if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS) | ||
470 | return 0; | ||
471 | |||
471 | return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm); | 472 | return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm); |
472 | } | 473 | } |
473 | 474 | ||
@@ -480,14 +481,18 @@ static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) | |||
480 | * be accessed by a particular initiator (e.g., if a module will not | 481 | * be accessed by a particular initiator (e.g., if a module will not |
481 | * be accessed by the IVA, there should be no sleepdep between the IVA | 482 | * be accessed by the IVA, there should be no sleepdep between the IVA |
482 | * initiator and the module). Only applies to modules in smart-idle | 483 | * initiator and the module). Only applies to modules in smart-idle |
483 | * mode. Returns -EINVAL upon error or passes along | 484 | * mode. If the clockdomain is marked as not needing autodeps, return |
484 | * clkdm_del_sleepdep() value upon success. | 485 | * 0 without doing anything. Returns -EINVAL upon error or passes |
486 | * along clkdm_del_sleepdep() value upon success. | ||
485 | */ | 487 | */ |
486 | static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) | 488 | static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) |
487 | { | 489 | { |
488 | if (!oh->_clk) | 490 | if (!oh->_clk) |
489 | return -EINVAL; | 491 | return -EINVAL; |
490 | 492 | ||
493 | if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS) | ||
494 | return 0; | ||
495 | |||
491 | return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm); | 496 | return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm); |
492 | } | 497 | } |
493 | 498 | ||
@@ -904,18 +909,16 @@ static struct omap_hwmod *_lookup(const char *name) | |||
904 | * @oh: struct omap_hwmod * | 909 | * @oh: struct omap_hwmod * |
905 | * @data: not used; pass NULL | 910 | * @data: not used; pass NULL |
906 | * | 911 | * |
907 | * Called by omap_hwmod_late_init() (after omap2_clk_init()). | 912 | * Called by omap_hwmod_setup_*() (after omap2_clk_init()). |
908 | * Resolves all clock names embedded in the hwmod. Returns -EINVAL if | 913 | * Resolves all clock names embedded in the hwmod. Returns 0 on |
909 | * the omap_hwmod has not yet been registered or if the clocks have | 914 | * success, or a negative error code on failure. |
910 | * already been initialized, 0 on success, or a non-zero error on | ||
911 | * failure. | ||
912 | */ | 915 | */ |
913 | static int _init_clocks(struct omap_hwmod *oh, void *data) | 916 | static int _init_clocks(struct omap_hwmod *oh, void *data) |
914 | { | 917 | { |
915 | int ret = 0; | 918 | int ret = 0; |
916 | 919 | ||
917 | if (!oh || (oh->_state != _HWMOD_STATE_REGISTERED)) | 920 | if (oh->_state != _HWMOD_STATE_REGISTERED) |
918 | return -EINVAL; | 921 | return 0; |
919 | 922 | ||
920 | pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name); | 923 | pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name); |
921 | 924 | ||
@@ -1288,6 +1291,42 @@ static int _idle(struct omap_hwmod *oh) | |||
1288 | } | 1291 | } |
1289 | 1292 | ||
1290 | /** | 1293 | /** |
1294 | * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit | ||
1295 | * @oh: struct omap_hwmod * | ||
1296 | * @autoidle: desired AUTOIDLE bitfield value (0 or 1) | ||
1297 | * | ||
1298 | * Sets the IP block's OCP autoidle bit in hardware, and updates our | ||
1299 | * local copy. Intended to be used by drivers that require | ||
1300 | * direct manipulation of the AUTOIDLE bits. | ||
1301 | * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes | ||
1302 | * along the return value from _set_module_autoidle(). | ||
1303 | * | ||
1304 | * Any users of this function should be scrutinized carefully. | ||
1305 | */ | ||
1306 | int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle) | ||
1307 | { | ||
1308 | u32 v; | ||
1309 | int retval = 0; | ||
1310 | unsigned long flags; | ||
1311 | |||
1312 | if (!oh || oh->_state != _HWMOD_STATE_ENABLED) | ||
1313 | return -EINVAL; | ||
1314 | |||
1315 | spin_lock_irqsave(&oh->_lock, flags); | ||
1316 | |||
1317 | v = oh->_sysc_cache; | ||
1318 | |||
1319 | retval = _set_module_autoidle(oh, autoidle, &v); | ||
1320 | |||
1321 | if (!retval) | ||
1322 | _write_sysconfig(v, oh); | ||
1323 | |||
1324 | spin_unlock_irqrestore(&oh->_lock, flags); | ||
1325 | |||
1326 | return retval; | ||
1327 | } | ||
1328 | |||
1329 | /** | ||
1291 | * _shutdown - shutdown an omap_hwmod | 1330 | * _shutdown - shutdown an omap_hwmod |
1292 | * @oh: struct omap_hwmod * | 1331 | * @oh: struct omap_hwmod * |
1293 | * | 1332 | * |
@@ -1354,14 +1393,16 @@ static int _shutdown(struct omap_hwmod *oh) | |||
1354 | * @oh: struct omap_hwmod * | 1393 | * @oh: struct omap_hwmod * |
1355 | * | 1394 | * |
1356 | * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh | 1395 | * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh |
1357 | * OCP_SYSCONFIG register. Returns -EINVAL if the hwmod is in the | 1396 | * OCP_SYSCONFIG register. Returns 0. |
1358 | * wrong state or returns 0. | ||
1359 | */ | 1397 | */ |
1360 | static int _setup(struct omap_hwmod *oh, void *data) | 1398 | static int _setup(struct omap_hwmod *oh, void *data) |
1361 | { | 1399 | { |
1362 | int i, r; | 1400 | int i, r; |
1363 | u8 postsetup_state; | 1401 | u8 postsetup_state; |
1364 | 1402 | ||
1403 | if (oh->_state != _HWMOD_STATE_CLKS_INITED) | ||
1404 | return 0; | ||
1405 | |||
1365 | /* Set iclk autoidle mode */ | 1406 | /* Set iclk autoidle mode */ |
1366 | if (oh->slaves_cnt > 0) { | 1407 | if (oh->slaves_cnt > 0) { |
1367 | for (i = 0; i < oh->slaves_cnt; i++) { | 1408 | for (i = 0; i < oh->slaves_cnt; i++) { |
@@ -1455,7 +1496,7 @@ static int _setup(struct omap_hwmod *oh, void *data) | |||
1455 | */ | 1496 | */ |
1456 | static int __init _register(struct omap_hwmod *oh) | 1497 | static int __init _register(struct omap_hwmod *oh) |
1457 | { | 1498 | { |
1458 | int ret, ms_id; | 1499 | int ms_id; |
1459 | 1500 | ||
1460 | if (!oh || !oh->name || !oh->class || !oh->class->name || | 1501 | if (!oh || !oh->name || !oh->class || !oh->class->name || |
1461 | (oh->_state != _HWMOD_STATE_UNKNOWN)) | 1502 | (oh->_state != _HWMOD_STATE_UNKNOWN)) |
@@ -1467,12 +1508,10 @@ static int __init _register(struct omap_hwmod *oh) | |||
1467 | return -EEXIST; | 1508 | return -EEXIST; |
1468 | 1509 | ||
1469 | ms_id = _find_mpu_port_index(oh); | 1510 | ms_id = _find_mpu_port_index(oh); |
1470 | if (!IS_ERR_VALUE(ms_id)) { | 1511 | if (!IS_ERR_VALUE(ms_id)) |
1471 | oh->_mpu_port_index = ms_id; | 1512 | oh->_mpu_port_index = ms_id; |
1472 | oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index); | 1513 | else |
1473 | } else { | ||
1474 | oh->_int_flags |= _HWMOD_NO_MPU_PORT; | 1514 | oh->_int_flags |= _HWMOD_NO_MPU_PORT; |
1475 | } | ||
1476 | 1515 | ||
1477 | list_add_tail(&oh->node, &omap_hwmod_list); | 1516 | list_add_tail(&oh->node, &omap_hwmod_list); |
1478 | 1517 | ||
@@ -1480,9 +1519,14 @@ static int __init _register(struct omap_hwmod *oh) | |||
1480 | 1519 | ||
1481 | oh->_state = _HWMOD_STATE_REGISTERED; | 1520 | oh->_state = _HWMOD_STATE_REGISTERED; |
1482 | 1521 | ||
1483 | ret = 0; | 1522 | /* |
1523 | * XXX Rather than doing a strcmp(), this should test a flag | ||
1524 | * set in the hwmod data, inserted by the autogenerator code. | ||
1525 | */ | ||
1526 | if (!strcmp(oh->name, MPU_INITIATOR_NAME)) | ||
1527 | mpu_oh = oh; | ||
1484 | 1528 | ||
1485 | return ret; | 1529 | return 0; |
1486 | } | 1530 | } |
1487 | 1531 | ||
1488 | 1532 | ||
@@ -1585,65 +1629,132 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), | |||
1585 | return ret; | 1629 | return ret; |
1586 | } | 1630 | } |
1587 | 1631 | ||
1588 | |||
1589 | /** | 1632 | /** |
1590 | * omap_hwmod_init - init omap_hwmod code and register hwmods | 1633 | * omap_hwmod_register - register an array of hwmods |
1591 | * @ohs: pointer to an array of omap_hwmods to register | 1634 | * @ohs: pointer to an array of omap_hwmods to register |
1592 | * | 1635 | * |
1593 | * Intended to be called early in boot before the clock framework is | 1636 | * Intended to be called early in boot before the clock framework is |
1594 | * initialized. If @ohs is not null, will register all omap_hwmods | 1637 | * initialized. If @ohs is not null, will register all omap_hwmods |
1595 | * listed in @ohs that are valid for this chip. Returns -EINVAL if | 1638 | * listed in @ohs that are valid for this chip. Returns 0. |
1596 | * omap_hwmod_init() has already been called or 0 otherwise. | 1639 | */ |
1640 | int __init omap_hwmod_register(struct omap_hwmod **ohs) | ||
1641 | { | ||
1642 | int r, i; | ||
1643 | |||
1644 | if (!ohs) | ||
1645 | return 0; | ||
1646 | |||
1647 | i = 0; | ||
1648 | do { | ||
1649 | if (!omap_chip_is(ohs[i]->omap_chip)) | ||
1650 | continue; | ||
1651 | |||
1652 | r = _register(ohs[i]); | ||
1653 | WARN(r, "omap_hwmod: %s: _register returned %d\n", ohs[i]->name, | ||
1654 | r); | ||
1655 | } while (ohs[++i]); | ||
1656 | |||
1657 | return 0; | ||
1658 | } | ||
1659 | |||
1660 | /* | ||
1661 | * _populate_mpu_rt_base - populate the virtual address for a hwmod | ||
1662 | * | ||
1663 | * Must be called only from omap_hwmod_setup_*() so ioremap works properly. | ||
1664 | * Assumes the caller takes care of locking if needed. | ||
1597 | */ | 1665 | */ |
1598 | int __init omap_hwmod_init(struct omap_hwmod **ohs) | 1666 | static int __init _populate_mpu_rt_base(struct omap_hwmod *oh, void *data) |
1667 | { | ||
1668 | if (oh->_state != _HWMOD_STATE_REGISTERED) | ||
1669 | return 0; | ||
1670 | |||
1671 | if (oh->_int_flags & _HWMOD_NO_MPU_PORT) | ||
1672 | return 0; | ||
1673 | |||
1674 | oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index); | ||
1675 | if (!oh->_mpu_rt_va) | ||
1676 | pr_warning("omap_hwmod: %s found no _mpu_rt_va for %s\n", | ||
1677 | __func__, oh->name); | ||
1678 | |||
1679 | return 0; | ||
1680 | } | ||
1681 | |||
1682 | /** | ||
1683 | * omap_hwmod_setup_one - set up a single hwmod | ||
1684 | * @oh_name: const char * name of the already-registered hwmod to set up | ||
1685 | * | ||
1686 | * Must be called after omap2_clk_init(). Resolves the struct clk | ||
1687 | * names to struct clk pointers for each registered omap_hwmod. Also | ||
1688 | * calls _setup() on each hwmod. Returns -EINVAL upon error or 0 upon | ||
1689 | * success. | ||
1690 | */ | ||
1691 | int __init omap_hwmod_setup_one(const char *oh_name) | ||
1599 | { | 1692 | { |
1600 | struct omap_hwmod *oh; | 1693 | struct omap_hwmod *oh; |
1601 | int r; | 1694 | int r; |
1602 | 1695 | ||
1603 | if (inited) | 1696 | pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__); |
1697 | |||
1698 | if (!mpu_oh) { | ||
1699 | pr_err("omap_hwmod: %s: cannot setup_one: MPU initiator hwmod %s not yet registered\n", | ||
1700 | oh_name, MPU_INITIATOR_NAME); | ||
1604 | return -EINVAL; | 1701 | return -EINVAL; |
1702 | } | ||
1605 | 1703 | ||
1606 | inited = 1; | 1704 | oh = _lookup(oh_name); |
1705 | if (!oh) { | ||
1706 | WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name); | ||
1707 | return -EINVAL; | ||
1708 | } | ||
1607 | 1709 | ||
1608 | if (!ohs) | 1710 | if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh) |
1609 | return 0; | 1711 | omap_hwmod_setup_one(MPU_INITIATOR_NAME); |
1610 | 1712 | ||
1611 | oh = *ohs; | 1713 | r = _populate_mpu_rt_base(oh, NULL); |
1612 | while (oh) { | 1714 | if (IS_ERR_VALUE(r)) { |
1613 | if (omap_chip_is(oh->omap_chip)) { | 1715 | WARN(1, "omap_hwmod: %s: couldn't set mpu_rt_base\n", oh_name); |
1614 | r = _register(oh); | 1716 | return -EINVAL; |
1615 | WARN(r, "omap_hwmod: %s: _register returned " | 1717 | } |
1616 | "%d\n", oh->name, r); | 1718 | |
1617 | } | 1719 | r = _init_clocks(oh, NULL); |
1618 | oh = *++ohs; | 1720 | if (IS_ERR_VALUE(r)) { |
1721 | WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh_name); | ||
1722 | return -EINVAL; | ||
1619 | } | 1723 | } |
1620 | 1724 | ||
1725 | _setup(oh, NULL); | ||
1726 | |||
1621 | return 0; | 1727 | return 0; |
1622 | } | 1728 | } |
1623 | 1729 | ||
1624 | /** | 1730 | /** |
1625 | * omap_hwmod_late_init - do some post-clock framework initialization | 1731 | * omap_hwmod_setup - do some post-clock framework initialization |
1626 | * | 1732 | * |
1627 | * Must be called after omap2_clk_init(). Resolves the struct clk names | 1733 | * Must be called after omap2_clk_init(). Resolves the struct clk names |
1628 | * to struct clk pointers for each registered omap_hwmod. Also calls | 1734 | * to struct clk pointers for each registered omap_hwmod. Also calls |
1629 | * _setup() on each hwmod. Returns 0. | 1735 | * _setup() on each hwmod. Returns 0 upon success. |
1630 | */ | 1736 | */ |
1631 | int omap_hwmod_late_init(void) | 1737 | static int __init omap_hwmod_setup_all(void) |
1632 | { | 1738 | { |
1633 | int r; | 1739 | int r; |
1634 | 1740 | ||
1635 | /* XXX check return value */ | 1741 | if (!mpu_oh) { |
1636 | r = omap_hwmod_for_each(_init_clocks, NULL); | 1742 | pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n", |
1637 | WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n"); | 1743 | __func__, MPU_INITIATOR_NAME); |
1744 | return -EINVAL; | ||
1745 | } | ||
1746 | |||
1747 | r = omap_hwmod_for_each(_populate_mpu_rt_base, NULL); | ||
1638 | 1748 | ||
1639 | mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME); | 1749 | r = omap_hwmod_for_each(_init_clocks, NULL); |
1640 | WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n", | 1750 | WARN(IS_ERR_VALUE(r), |
1641 | MPU_INITIATOR_NAME); | 1751 | "omap_hwmod: %s: _init_clocks failed\n", __func__); |
1642 | 1752 | ||
1643 | omap_hwmod_for_each(_setup, NULL); | 1753 | omap_hwmod_for_each(_setup, NULL); |
1644 | 1754 | ||
1645 | return 0; | 1755 | return 0; |
1646 | } | 1756 | } |
1757 | core_initcall(omap_hwmod_setup_all); | ||
1647 | 1758 | ||
1648 | /** | 1759 | /** |
1649 | * omap_hwmod_enable - enable an omap_hwmod | 1760 | * omap_hwmod_enable - enable an omap_hwmod |
@@ -1862,6 +1973,7 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) | |||
1862 | os = oh->slaves[i]; | 1973 | os = oh->slaves[i]; |
1863 | 1974 | ||
1864 | for (j = 0; j < os->addr_cnt; j++) { | 1975 | for (j = 0; j < os->addr_cnt; j++) { |
1976 | (res + r)->name = (os->addr + j)->name; | ||
1865 | (res + r)->start = (os->addr + j)->pa_start; | 1977 | (res + r)->start = (os->addr + j)->pa_start; |
1866 | (res + r)->end = (os->addr + j)->pa_end; | 1978 | (res + r)->end = (os->addr + j)->pa_end; |
1867 | (res + r)->flags = IORESOURCE_MEM; | 1979 | (res + r)->flags = IORESOURCE_MEM; |
@@ -2162,11 +2274,11 @@ int omap_hwmod_for_each_by_class(const char *classname, | |||
2162 | * @oh: struct omap_hwmod * | 2274 | * @oh: struct omap_hwmod * |
2163 | * @state: state that _setup() should leave the hwmod in | 2275 | * @state: state that _setup() should leave the hwmod in |
2164 | * | 2276 | * |
2165 | * Sets the hwmod state that @oh will enter at the end of _setup() (called by | 2277 | * Sets the hwmod state that @oh will enter at the end of _setup() |
2166 | * omap_hwmod_late_init()). Only valid to call between calls to | 2278 | * (called by omap_hwmod_setup_*()). Only valid to call between |
2167 | * omap_hwmod_init() and omap_hwmod_late_init(). Returns 0 upon success or | 2279 | * calling omap_hwmod_register() and omap_hwmod_setup_*(). Returns |
2168 | * -EINVAL if there is a problem with the arguments or if the hwmod is | 2280 | * 0 upon success or -EINVAL if there is a problem with the arguments |
2169 | * in the wrong state. | 2281 | * or if the hwmod is in the wrong state. |
2170 | */ | 2282 | */ |
2171 | int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state) | 2283 | int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state) |
2172 | { | 2284 | { |
@@ -2218,3 +2330,29 @@ u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh) | |||
2218 | 2330 | ||
2219 | return ret; | 2331 | return ret; |
2220 | } | 2332 | } |
2333 | |||
2334 | /** | ||
2335 | * omap_hwmod_no_setup_reset - prevent a hwmod from being reset upon setup | ||
2336 | * @oh: struct omap_hwmod * | ||
2337 | * | ||
2338 | * Prevent the hwmod @oh from being reset during the setup process. | ||
2339 | * Intended for use by board-*.c files on boards with devices that | ||
2340 | * cannot tolerate being reset. Must be called before the hwmod has | ||
2341 | * been set up. Returns 0 upon success or negative error code upon | ||
2342 | * failure. | ||
2343 | */ | ||
2344 | int omap_hwmod_no_setup_reset(struct omap_hwmod *oh) | ||
2345 | { | ||
2346 | if (!oh) | ||
2347 | return -EINVAL; | ||
2348 | |||
2349 | if (oh->_state != _HWMOD_STATE_REGISTERED) { | ||
2350 | pr_err("omap_hwmod: %s: cannot prevent setup reset; in wrong state\n", | ||
2351 | oh->name); | ||
2352 | return -EINVAL; | ||
2353 | } | ||
2354 | |||
2355 | oh->flags |= HWMOD_INIT_NO_RESET; | ||
2356 | |||
2357 | return 0; | ||
2358 | } | ||