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.c333
1 files changed, 242 insertions, 91 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index e282e35769fd..e03429453ce7 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 */
163static struct omap_hwmod *mpu_oh; 163static struct omap_hwmod *mpu_oh;
164 164
165/* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */
166static u8 inited;
167
168 165
169/* Private functions */ 166/* Private functions */
170 167
@@ -373,7 +370,7 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
373 } 370 }
374 371
375 autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift; 372 autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift;
376 autoidle_mask = (0x3 << autoidle_shift); 373 autoidle_mask = (0x1 << autoidle_shift);
377 374
378 *v &= ~autoidle_mask; 375 *v &= ~autoidle_mask;
379 *v |= autoidle << autoidle_shift; 376 *v |= autoidle << autoidle_shift;
@@ -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 */
466static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) 464static 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 */
486static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) 488static 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 */
913static int _init_clocks(struct omap_hwmod *oh, void *data) 916static 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
@@ -926,7 +929,7 @@ static int _init_clocks(struct omap_hwmod *oh, void *data)
926 if (!ret) 929 if (!ret)
927 oh->_state = _HWMOD_STATE_CLKS_INITED; 930 oh->_state = _HWMOD_STATE_CLKS_INITED;
928 931
929 return 0; 932 return ret;
930} 933}
931 934
932/** 935/**
@@ -972,25 +975,29 @@ static int _wait_target_ready(struct omap_hwmod *oh)
972} 975}
973 976
974/** 977/**
975 * _lookup_hardreset - return the register bit shift for this hwmod/reset line 978 * _lookup_hardreset - fill register bit info for this hwmod/reset line
976 * @oh: struct omap_hwmod * 979 * @oh: struct omap_hwmod *
977 * @name: name of the reset line in the context of this hwmod 980 * @name: name of the reset line in the context of this hwmod
981 * @ohri: struct omap_hwmod_rst_info * that this function will fill in
978 * 982 *
979 * Return the bit position of the reset line that match the 983 * Return the bit position of the reset line that match the
980 * input name. Return -ENOENT if not found. 984 * input name. Return -ENOENT if not found.
981 */ 985 */
982static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name) 986static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name,
987 struct omap_hwmod_rst_info *ohri)
983{ 988{
984 int i; 989 int i;
985 990
986 for (i = 0; i < oh->rst_lines_cnt; i++) { 991 for (i = 0; i < oh->rst_lines_cnt; i++) {
987 const char *rst_line = oh->rst_lines[i].name; 992 const char *rst_line = oh->rst_lines[i].name;
988 if (!strcmp(rst_line, name)) { 993 if (!strcmp(rst_line, name)) {
989 u8 shift = oh->rst_lines[i].rst_shift; 994 ohri->rst_shift = oh->rst_lines[i].rst_shift;
990 pr_debug("omap_hwmod: %s: _lookup_hardreset: %s: %d\n", 995 ohri->st_shift = oh->rst_lines[i].st_shift;
991 oh->name, rst_line, shift); 996 pr_debug("omap_hwmod: %s: %s: %s: rst %d st %d\n",
997 oh->name, __func__, rst_line, ohri->rst_shift,
998 ohri->st_shift);
992 999
993 return shift; 1000 return 0;
994 } 1001 }
995 } 1002 }
996 1003
@@ -1009,21 +1016,22 @@ static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name)
1009 */ 1016 */
1010static int _assert_hardreset(struct omap_hwmod *oh, const char *name) 1017static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
1011{ 1018{
1012 u8 shift; 1019 struct omap_hwmod_rst_info ohri;
1020 u8 ret;
1013 1021
1014 if (!oh) 1022 if (!oh)
1015 return -EINVAL; 1023 return -EINVAL;
1016 1024
1017 shift = _lookup_hardreset(oh, name); 1025 ret = _lookup_hardreset(oh, name, &ohri);
1018 if (IS_ERR_VALUE(shift)) 1026 if (IS_ERR_VALUE(ret))
1019 return shift; 1027 return ret;
1020 1028
1021 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 1029 if (cpu_is_omap24xx() || cpu_is_omap34xx())
1022 return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, 1030 return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
1023 shift); 1031 ohri.rst_shift);
1024 else if (cpu_is_omap44xx()) 1032 else if (cpu_is_omap44xx())
1025 return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg, 1033 return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg,
1026 shift); 1034 ohri.rst_shift);
1027 else 1035 else
1028 return -EINVAL; 1036 return -EINVAL;
1029} 1037}
@@ -1040,29 +1048,34 @@ static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
1040 */ 1048 */
1041static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) 1049static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
1042{ 1050{
1043 u8 shift; 1051 struct omap_hwmod_rst_info ohri;
1044 int r; 1052 int ret;
1045 1053
1046 if (!oh) 1054 if (!oh)
1047 return -EINVAL; 1055 return -EINVAL;
1048 1056
1049 shift = _lookup_hardreset(oh, name); 1057 ret = _lookup_hardreset(oh, name, &ohri);
1050 if (IS_ERR_VALUE(shift)) 1058 if (IS_ERR_VALUE(ret))
1051 return shift; 1059 return ret;
1052 1060
1053 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 1061 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1054 r = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, 1062 ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
1055 shift); 1063 ohri.rst_shift,
1056 else if (cpu_is_omap44xx()) 1064 ohri.st_shift);
1057 r = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg, 1065 } else if (cpu_is_omap44xx()) {
1058 shift); 1066 if (ohri.st_shift)
1059 else 1067 pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
1068 oh->name, name);
1069 ret = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg,
1070 ohri.rst_shift);
1071 } else {
1060 return -EINVAL; 1072 return -EINVAL;
1073 }
1061 1074
1062 if (r == -EBUSY) 1075 if (ret == -EBUSY)
1063 pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name); 1076 pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
1064 1077
1065 return r; 1078 return ret;
1066} 1079}
1067 1080
1068/** 1081/**
@@ -1075,21 +1088,22 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
1075 */ 1088 */
1076static int _read_hardreset(struct omap_hwmod *oh, const char *name) 1089static int _read_hardreset(struct omap_hwmod *oh, const char *name)
1077{ 1090{
1078 u8 shift; 1091 struct omap_hwmod_rst_info ohri;
1092 u8 ret;
1079 1093
1080 if (!oh) 1094 if (!oh)
1081 return -EINVAL; 1095 return -EINVAL;
1082 1096
1083 shift = _lookup_hardreset(oh, name); 1097 ret = _lookup_hardreset(oh, name, &ohri);
1084 if (IS_ERR_VALUE(shift)) 1098 if (IS_ERR_VALUE(ret))
1085 return shift; 1099 return ret;
1086 1100
1087 if (cpu_is_omap24xx() || cpu_is_omap34xx()) { 1101 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1088 return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, 1102 return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
1089 shift); 1103 ohri.st_shift);
1090 } else if (cpu_is_omap44xx()) { 1104 } else if (cpu_is_omap44xx()) {
1091 return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg, 1105 return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg,
1092 shift); 1106 ohri.rst_shift);
1093 } else { 1107 } else {
1094 return -EINVAL; 1108 return -EINVAL;
1095 } 1109 }
@@ -1230,7 +1244,9 @@ static int _enable(struct omap_hwmod *oh)
1230 _deassert_hardreset(oh, oh->rst_lines[0].name); 1244 _deassert_hardreset(oh, oh->rst_lines[0].name);
1231 1245
1232 /* Mux pins for device runtime if populated */ 1246 /* Mux pins for device runtime if populated */
1233 if (oh->mux) 1247 if (oh->mux && (!oh->mux->enabled ||
1248 ((oh->_state == _HWMOD_STATE_IDLE) &&
1249 oh->mux->pads_dynamic)))
1234 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); 1250 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
1235 1251
1236 _add_initiator_dep(oh, mpu_oh); 1252 _add_initiator_dep(oh, mpu_oh);
@@ -1279,7 +1295,7 @@ static int _idle(struct omap_hwmod *oh)
1279 _disable_clocks(oh); 1295 _disable_clocks(oh);
1280 1296
1281 /* Mux pins for device idle if populated */ 1297 /* Mux pins for device idle if populated */
1282 if (oh->mux) 1298 if (oh->mux && oh->mux->pads_dynamic)
1283 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); 1299 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
1284 1300
1285 oh->_state = _HWMOD_STATE_IDLE; 1301 oh->_state = _HWMOD_STATE_IDLE;
@@ -1288,6 +1304,42 @@ static int _idle(struct omap_hwmod *oh)
1288} 1304}
1289 1305
1290/** 1306/**
1307 * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit
1308 * @oh: struct omap_hwmod *
1309 * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
1310 *
1311 * Sets the IP block's OCP autoidle bit in hardware, and updates our
1312 * local copy. Intended to be used by drivers that require
1313 * direct manipulation of the AUTOIDLE bits.
1314 * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes
1315 * along the return value from _set_module_autoidle().
1316 *
1317 * Any users of this function should be scrutinized carefully.
1318 */
1319int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle)
1320{
1321 u32 v;
1322 int retval = 0;
1323 unsigned long flags;
1324
1325 if (!oh || oh->_state != _HWMOD_STATE_ENABLED)
1326 return -EINVAL;
1327
1328 spin_lock_irqsave(&oh->_lock, flags);
1329
1330 v = oh->_sysc_cache;
1331
1332 retval = _set_module_autoidle(oh, autoidle, &v);
1333
1334 if (!retval)
1335 _write_sysconfig(v, oh);
1336
1337 spin_unlock_irqrestore(&oh->_lock, flags);
1338
1339 return retval;
1340}
1341
1342/**
1291 * _shutdown - shutdown an omap_hwmod 1343 * _shutdown - shutdown an omap_hwmod
1292 * @oh: struct omap_hwmod * 1344 * @oh: struct omap_hwmod *
1293 * 1345 *
@@ -1354,14 +1406,16 @@ static int _shutdown(struct omap_hwmod *oh)
1354 * @oh: struct omap_hwmod * 1406 * @oh: struct omap_hwmod *
1355 * 1407 *
1356 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh 1408 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
1357 * OCP_SYSCONFIG register. Returns -EINVAL if the hwmod is in the 1409 * OCP_SYSCONFIG register. Returns 0.
1358 * wrong state or returns 0.
1359 */ 1410 */
1360static int _setup(struct omap_hwmod *oh, void *data) 1411static int _setup(struct omap_hwmod *oh, void *data)
1361{ 1412{
1362 int i, r; 1413 int i, r;
1363 u8 postsetup_state; 1414 u8 postsetup_state;
1364 1415
1416 if (oh->_state != _HWMOD_STATE_CLKS_INITED)
1417 return 0;
1418
1365 /* Set iclk autoidle mode */ 1419 /* Set iclk autoidle mode */
1366 if (oh->slaves_cnt > 0) { 1420 if (oh->slaves_cnt > 0) {
1367 for (i = 0; i < oh->slaves_cnt; i++) { 1421 for (i = 0; i < oh->slaves_cnt; i++) {
@@ -1455,7 +1509,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
1455 */ 1509 */
1456static int __init _register(struct omap_hwmod *oh) 1510static int __init _register(struct omap_hwmod *oh)
1457{ 1511{
1458 int ret, ms_id; 1512 int ms_id;
1459 1513
1460 if (!oh || !oh->name || !oh->class || !oh->class->name || 1514 if (!oh || !oh->name || !oh->class || !oh->class->name ||
1461 (oh->_state != _HWMOD_STATE_UNKNOWN)) 1515 (oh->_state != _HWMOD_STATE_UNKNOWN))
@@ -1467,12 +1521,10 @@ static int __init _register(struct omap_hwmod *oh)
1467 return -EEXIST; 1521 return -EEXIST;
1468 1522
1469 ms_id = _find_mpu_port_index(oh); 1523 ms_id = _find_mpu_port_index(oh);
1470 if (!IS_ERR_VALUE(ms_id)) { 1524 if (!IS_ERR_VALUE(ms_id))
1471 oh->_mpu_port_index = ms_id; 1525 oh->_mpu_port_index = ms_id;
1472 oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index); 1526 else
1473 } else {
1474 oh->_int_flags |= _HWMOD_NO_MPU_PORT; 1527 oh->_int_flags |= _HWMOD_NO_MPU_PORT;
1475 }
1476 1528
1477 list_add_tail(&oh->node, &omap_hwmod_list); 1529 list_add_tail(&oh->node, &omap_hwmod_list);
1478 1530
@@ -1480,9 +1532,14 @@ static int __init _register(struct omap_hwmod *oh)
1480 1532
1481 oh->_state = _HWMOD_STATE_REGISTERED; 1533 oh->_state = _HWMOD_STATE_REGISTERED;
1482 1534
1483 ret = 0; 1535 /*
1536 * XXX Rather than doing a strcmp(), this should test a flag
1537 * set in the hwmod data, inserted by the autogenerator code.
1538 */
1539 if (!strcmp(oh->name, MPU_INITIATOR_NAME))
1540 mpu_oh = oh;
1484 1541
1485 return ret; 1542 return 0;
1486} 1543}
1487 1544
1488 1545
@@ -1585,65 +1642,132 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
1585 return ret; 1642 return ret;
1586} 1643}
1587 1644
1588
1589/** 1645/**
1590 * omap_hwmod_init - init omap_hwmod code and register hwmods 1646 * omap_hwmod_register - register an array of hwmods
1591 * @ohs: pointer to an array of omap_hwmods to register 1647 * @ohs: pointer to an array of omap_hwmods to register
1592 * 1648 *
1593 * Intended to be called early in boot before the clock framework is 1649 * Intended to be called early in boot before the clock framework is
1594 * initialized. If @ohs is not null, will register all omap_hwmods 1650 * initialized. If @ohs is not null, will register all omap_hwmods
1595 * listed in @ohs that are valid for this chip. Returns -EINVAL if 1651 * listed in @ohs that are valid for this chip. Returns 0.
1596 * omap_hwmod_init() has already been called or 0 otherwise.
1597 */ 1652 */
1598int __init omap_hwmod_init(struct omap_hwmod **ohs) 1653int __init omap_hwmod_register(struct omap_hwmod **ohs)
1654{
1655 int r, i;
1656
1657 if (!ohs)
1658 return 0;
1659
1660 i = 0;
1661 do {
1662 if (!omap_chip_is(ohs[i]->omap_chip))
1663 continue;
1664
1665 r = _register(ohs[i]);
1666 WARN(r, "omap_hwmod: %s: _register returned %d\n", ohs[i]->name,
1667 r);
1668 } while (ohs[++i]);
1669
1670 return 0;
1671}
1672
1673/*
1674 * _populate_mpu_rt_base - populate the virtual address for a hwmod
1675 *
1676 * Must be called only from omap_hwmod_setup_*() so ioremap works properly.
1677 * Assumes the caller takes care of locking if needed.
1678 */
1679static int __init _populate_mpu_rt_base(struct omap_hwmod *oh, void *data)
1680{
1681 if (oh->_state != _HWMOD_STATE_REGISTERED)
1682 return 0;
1683
1684 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1685 return 0;
1686
1687 oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
1688 if (!oh->_mpu_rt_va)
1689 pr_warning("omap_hwmod: %s found no _mpu_rt_va for %s\n",
1690 __func__, oh->name);
1691
1692 return 0;
1693}
1694
1695/**
1696 * omap_hwmod_setup_one - set up a single hwmod
1697 * @oh_name: const char * name of the already-registered hwmod to set up
1698 *
1699 * Must be called after omap2_clk_init(). Resolves the struct clk
1700 * names to struct clk pointers for each registered omap_hwmod. Also
1701 * calls _setup() on each hwmod. Returns -EINVAL upon error or 0 upon
1702 * success.
1703 */
1704int __init omap_hwmod_setup_one(const char *oh_name)
1599{ 1705{
1600 struct omap_hwmod *oh; 1706 struct omap_hwmod *oh;
1601 int r; 1707 int r;
1602 1708
1603 if (inited) 1709 pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__);
1710
1711 if (!mpu_oh) {
1712 pr_err("omap_hwmod: %s: cannot setup_one: MPU initiator hwmod %s not yet registered\n",
1713 oh_name, MPU_INITIATOR_NAME);
1604 return -EINVAL; 1714 return -EINVAL;
1715 }
1605 1716
1606 inited = 1; 1717 oh = _lookup(oh_name);
1718 if (!oh) {
1719 WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name);
1720 return -EINVAL;
1721 }
1607 1722
1608 if (!ohs) 1723 if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh)
1609 return 0; 1724 omap_hwmod_setup_one(MPU_INITIATOR_NAME);
1610 1725
1611 oh = *ohs; 1726 r = _populate_mpu_rt_base(oh, NULL);
1612 while (oh) { 1727 if (IS_ERR_VALUE(r)) {
1613 if (omap_chip_is(oh->omap_chip)) { 1728 WARN(1, "omap_hwmod: %s: couldn't set mpu_rt_base\n", oh_name);
1614 r = _register(oh); 1729 return -EINVAL;
1615 WARN(r, "omap_hwmod: %s: _register returned "
1616 "%d\n", oh->name, r);
1617 }
1618 oh = *++ohs;
1619 } 1730 }
1620 1731
1732 r = _init_clocks(oh, NULL);
1733 if (IS_ERR_VALUE(r)) {
1734 WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh_name);
1735 return -EINVAL;
1736 }
1737
1738 _setup(oh, NULL);
1739
1621 return 0; 1740 return 0;
1622} 1741}
1623 1742
1624/** 1743/**
1625 * omap_hwmod_late_init - do some post-clock framework initialization 1744 * omap_hwmod_setup - do some post-clock framework initialization
1626 * 1745 *
1627 * Must be called after omap2_clk_init(). Resolves the struct clk names 1746 * Must be called after omap2_clk_init(). Resolves the struct clk names
1628 * to struct clk pointers for each registered omap_hwmod. Also calls 1747 * to struct clk pointers for each registered omap_hwmod. Also calls
1629 * _setup() on each hwmod. Returns 0. 1748 * _setup() on each hwmod. Returns 0 upon success.
1630 */ 1749 */
1631int omap_hwmod_late_init(void) 1750static int __init omap_hwmod_setup_all(void)
1632{ 1751{
1633 int r; 1752 int r;
1634 1753
1635 /* XXX check return value */ 1754 if (!mpu_oh) {
1636 r = omap_hwmod_for_each(_init_clocks, NULL); 1755 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"); 1756 __func__, MPU_INITIATOR_NAME);
1757 return -EINVAL;
1758 }
1638 1759
1639 mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME); 1760 r = omap_hwmod_for_each(_populate_mpu_rt_base, NULL);
1640 WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n", 1761
1641 MPU_INITIATOR_NAME); 1762 r = omap_hwmod_for_each(_init_clocks, NULL);
1763 WARN(IS_ERR_VALUE(r),
1764 "omap_hwmod: %s: _init_clocks failed\n", __func__);
1642 1765
1643 omap_hwmod_for_each(_setup, NULL); 1766 omap_hwmod_for_each(_setup, NULL);
1644 1767
1645 return 0; 1768 return 0;
1646} 1769}
1770core_initcall(omap_hwmod_setup_all);
1647 1771
1648/** 1772/**
1649 * omap_hwmod_enable - enable an omap_hwmod 1773 * omap_hwmod_enable - enable an omap_hwmod
@@ -1862,6 +1986,7 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
1862 os = oh->slaves[i]; 1986 os = oh->slaves[i];
1863 1987
1864 for (j = 0; j < os->addr_cnt; j++) { 1988 for (j = 0; j < os->addr_cnt; j++) {
1989 (res + r)->name = (os->addr + j)->name;
1865 (res + r)->start = (os->addr + j)->pa_start; 1990 (res + r)->start = (os->addr + j)->pa_start;
1866 (res + r)->end = (os->addr + j)->pa_end; 1991 (res + r)->end = (os->addr + j)->pa_end;
1867 (res + r)->flags = IORESOURCE_MEM; 1992 (res + r)->flags = IORESOURCE_MEM;
@@ -2162,11 +2287,11 @@ int omap_hwmod_for_each_by_class(const char *classname,
2162 * @oh: struct omap_hwmod * 2287 * @oh: struct omap_hwmod *
2163 * @state: state that _setup() should leave the hwmod in 2288 * @state: state that _setup() should leave the hwmod in
2164 * 2289 *
2165 * Sets the hwmod state that @oh will enter at the end of _setup() (called by 2290 * 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 2291 * (called by omap_hwmod_setup_*()). Only valid to call between
2167 * omap_hwmod_init() and omap_hwmod_late_init(). Returns 0 upon success or 2292 * calling omap_hwmod_register() and omap_hwmod_setup_*(). Returns
2168 * -EINVAL if there is a problem with the arguments or if the hwmod is 2293 * 0 upon success or -EINVAL if there is a problem with the arguments
2169 * in the wrong state. 2294 * or if the hwmod is in the wrong state.
2170 */ 2295 */
2171int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state) 2296int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
2172{ 2297{
@@ -2218,3 +2343,29 @@ u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
2218 2343
2219 return ret; 2344 return ret;
2220} 2345}
2346
2347/**
2348 * omap_hwmod_no_setup_reset - prevent a hwmod from being reset upon setup
2349 * @oh: struct omap_hwmod *
2350 *
2351 * Prevent the hwmod @oh from being reset during the setup process.
2352 * Intended for use by board-*.c files on boards with devices that
2353 * cannot tolerate being reset. Must be called before the hwmod has
2354 * been set up. Returns 0 upon success or negative error code upon
2355 * failure.
2356 */
2357int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
2358{
2359 if (!oh)
2360 return -EINVAL;
2361
2362 if (oh->_state != _HWMOD_STATE_REGISTERED) {
2363 pr_err("omap_hwmod: %s: cannot prevent setup reset; in wrong state\n",
2364 oh->name);
2365 return -EINVAL;
2366 }
2367
2368 oh->flags |= HWMOD_INIT_NO_RESET;
2369
2370 return 0;
2371}