diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-omap2/io.c | 32 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 82 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 |
3 files changed, 88 insertions, 32 deletions
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 77bf0d1baeef..7362b69a154d 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -312,6 +312,11 @@ static int __init _omap2_init_reprogram_sdrc(void) | |||
312 | return v; | 312 | return v; |
313 | } | 313 | } |
314 | 314 | ||
315 | static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data) | ||
316 | { | ||
317 | return omap_hwmod_set_postsetup_state(oh, *(u8 *)data); | ||
318 | } | ||
319 | |||
315 | /* | 320 | /* |
316 | * Initialize asm_irq_base for entry-macro.S | 321 | * Initialize asm_irq_base for entry-macro.S |
317 | */ | 322 | */ |
@@ -333,6 +338,8 @@ static inline void omap_irq_base_init(void) | |||
333 | 338 | ||
334 | void __init omap2_init_common_infrastructure(void) | 339 | void __init omap2_init_common_infrastructure(void) |
335 | { | 340 | { |
341 | u8 postsetup_state; | ||
342 | |||
336 | pwrdm_init(powerdomains_omap); | 343 | pwrdm_init(powerdomains_omap); |
337 | clkdm_init(clockdomains_omap, clkdm_autodeps); | 344 | clkdm_init(clockdomains_omap, clkdm_autodeps); |
338 | if (cpu_is_omap242x()) | 345 | if (cpu_is_omap242x()) |
@@ -343,6 +350,16 @@ void __init omap2_init_common_infrastructure(void) | |||
343 | omap3xxx_hwmod_init(); | 350 | omap3xxx_hwmod_init(); |
344 | else if (cpu_is_omap44xx()) | 351 | else if (cpu_is_omap44xx()) |
345 | omap44xx_hwmod_init(); | 352 | omap44xx_hwmod_init(); |
353 | else | ||
354 | pr_err("Could not init hwmod data - unknown SoC\n"); | ||
355 | |||
356 | /* Set the default postsetup state for all hwmods */ | ||
357 | #ifdef CONFIG_PM_RUNTIME | ||
358 | postsetup_state = _HWMOD_STATE_IDLE; | ||
359 | #else | ||
360 | postsetup_state = _HWMOD_STATE_ENABLED; | ||
361 | #endif | ||
362 | omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state); | ||
346 | 363 | ||
347 | omap_pm_if_early_init(); | 364 | omap_pm_if_early_init(); |
348 | 365 | ||
@@ -355,25 +372,16 @@ void __init omap2_init_common_infrastructure(void) | |||
355 | else if (cpu_is_omap44xx()) | 372 | else if (cpu_is_omap44xx()) |
356 | omap4xxx_clk_init(); | 373 | omap4xxx_clk_init(); |
357 | else | 374 | else |
358 | pr_err("Could not init clock framework - unknown CPU\n"); | 375 | pr_err("Could not init clock framework - unknown SoC\n"); |
359 | } | 376 | } |
360 | 377 | ||
361 | /* | ||
362 | * XXX Ideally, this function will dwindle into nothingness over time; | ||
363 | * almost all device init code should be possible through initcalls | ||
364 | * and other generalized mechanisms | ||
365 | */ | ||
366 | void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0, | 378 | void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0, |
367 | struct omap_sdrc_params *sdrc_cs1) | 379 | struct omap_sdrc_params *sdrc_cs1) |
368 | { | 380 | { |
369 | u8 skip_setup_idle = 0; | ||
370 | |||
371 | omap_serial_early_init(); | 381 | omap_serial_early_init(); |
372 | 382 | ||
373 | #ifndef CONFIG_PM_RUNTIME | 383 | omap_hwmod_late_init(); |
374 | skip_setup_idle = 1; | 384 | |
375 | #endif | ||
376 | omap_hwmod_late_init(skip_setup_idle); | ||
377 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | 385 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { |
378 | omap2_sdrc_init(sdrc_cs0, sdrc_cs1); | 386 | omap2_sdrc_init(sdrc_cs0, sdrc_cs1); |
379 | _omap2_init_reprogram_sdrc(); | 387 | _omap2_init_reprogram_sdrc(); |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index c051fa493594..683428fa91f4 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -1313,23 +1313,15 @@ static int _shutdown(struct omap_hwmod *oh) | |||
1313 | /** | 1313 | /** |
1314 | * _setup - do initial configuration of omap_hwmod | 1314 | * _setup - do initial configuration of omap_hwmod |
1315 | * @oh: struct omap_hwmod * | 1315 | * @oh: struct omap_hwmod * |
1316 | * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1 | ||
1317 | * | 1316 | * |
1318 | * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh | 1317 | * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh |
1319 | * OCP_SYSCONFIG register. @skip_setup_idle is intended to be used on | 1318 | * OCP_SYSCONFIG register. Returns -EINVAL if the hwmod is in the |
1320 | * a system that will not call omap_hwmod_enable() to enable devices | 1319 | * wrong state or returns 0. |
1321 | * (e.g., a system without PM runtime). Returns -EINVAL if the hwmod | ||
1322 | * is in the wrong state or returns 0. | ||
1323 | */ | 1320 | */ |
1324 | static int _setup(struct omap_hwmod *oh, void *data) | 1321 | static int _setup(struct omap_hwmod *oh, void *data) |
1325 | { | 1322 | { |
1326 | int i, r; | 1323 | int i, r; |
1327 | u8 skip_setup_idle; | 1324 | u8 postsetup_state; |
1328 | |||
1329 | if (!oh || !data) | ||
1330 | return -EINVAL; | ||
1331 | |||
1332 | skip_setup_idle = *(u8 *)data; | ||
1333 | 1325 | ||
1334 | /* Set iclk autoidle mode */ | 1326 | /* Set iclk autoidle mode */ |
1335 | if (oh->slaves_cnt > 0) { | 1327 | if (oh->slaves_cnt > 0) { |
@@ -1349,7 +1341,6 @@ static int _setup(struct omap_hwmod *oh, void *data) | |||
1349 | } | 1341 | } |
1350 | } | 1342 | } |
1351 | 1343 | ||
1352 | mutex_init(&oh->_mutex); | ||
1353 | oh->_state = _HWMOD_STATE_INITIALIZED; | 1344 | oh->_state = _HWMOD_STATE_INITIALIZED; |
1354 | 1345 | ||
1355 | /* | 1346 | /* |
@@ -1383,8 +1374,25 @@ static int _setup(struct omap_hwmod *oh, void *data) | |||
1383 | } | 1374 | } |
1384 | } | 1375 | } |
1385 | 1376 | ||
1386 | if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle) | 1377 | postsetup_state = oh->_postsetup_state; |
1378 | if (postsetup_state == _HWMOD_STATE_UNKNOWN) | ||
1379 | postsetup_state = _HWMOD_STATE_ENABLED; | ||
1380 | |||
1381 | /* | ||
1382 | * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data - | ||
1383 | * it should be set by the core code as a runtime flag during startup | ||
1384 | */ | ||
1385 | if ((oh->flags & HWMOD_INIT_NO_IDLE) && | ||
1386 | (postsetup_state == _HWMOD_STATE_IDLE)) | ||
1387 | postsetup_state = _HWMOD_STATE_ENABLED; | ||
1388 | |||
1389 | if (postsetup_state == _HWMOD_STATE_IDLE) | ||
1387 | _omap_hwmod_idle(oh); | 1390 | _omap_hwmod_idle(oh); |
1391 | else if (postsetup_state == _HWMOD_STATE_DISABLED) | ||
1392 | _shutdown(oh); | ||
1393 | else if (postsetup_state != _HWMOD_STATE_ENABLED) | ||
1394 | WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n", | ||
1395 | oh->name, postsetup_state); | ||
1388 | 1396 | ||
1389 | return 0; | 1397 | return 0; |
1390 | } | 1398 | } |
@@ -1485,6 +1493,8 @@ int omap_hwmod_register(struct omap_hwmod *oh) | |||
1485 | 1493 | ||
1486 | list_add_tail(&oh->node, &omap_hwmod_list); | 1494 | list_add_tail(&oh->node, &omap_hwmod_list); |
1487 | 1495 | ||
1496 | mutex_init(&oh->_mutex); | ||
1497 | |||
1488 | oh->_state = _HWMOD_STATE_REGISTERED; | 1498 | oh->_state = _HWMOD_STATE_REGISTERED; |
1489 | 1499 | ||
1490 | ret = 0; | 1500 | ret = 0; |
@@ -1585,13 +1595,12 @@ int omap_hwmod_init(struct omap_hwmod **ohs) | |||
1585 | 1595 | ||
1586 | /** | 1596 | /** |
1587 | * omap_hwmod_late_init - do some post-clock framework initialization | 1597 | * omap_hwmod_late_init - do some post-clock framework initialization |
1588 | * @skip_setup_idle: if 1, do not idle hwmods in _setup() | ||
1589 | * | 1598 | * |
1590 | * Must be called after omap2_clk_init(). Resolves the struct clk names | 1599 | * Must be called after omap2_clk_init(). Resolves the struct clk names |
1591 | * to struct clk pointers for each registered omap_hwmod. Also calls | 1600 | * to struct clk pointers for each registered omap_hwmod. Also calls |
1592 | * _setup() on each hwmod. Returns 0. | 1601 | * _setup() on each hwmod. Returns 0. |
1593 | */ | 1602 | */ |
1594 | int omap_hwmod_late_init(u8 skip_setup_idle) | 1603 | int omap_hwmod_late_init(void) |
1595 | { | 1604 | { |
1596 | int r; | 1605 | int r; |
1597 | 1606 | ||
@@ -1603,10 +1612,7 @@ int omap_hwmod_late_init(u8 skip_setup_idle) | |||
1603 | WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n", | 1612 | WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n", |
1604 | MPU_INITIATOR_NAME); | 1613 | MPU_INITIATOR_NAME); |
1605 | 1614 | ||
1606 | if (skip_setup_idle) | 1615 | omap_hwmod_for_each(_setup, NULL); |
1607 | pr_debug("omap_hwmod: will leave hwmods enabled during setup\n"); | ||
1608 | |||
1609 | omap_hwmod_for_each(_setup, &skip_setup_idle); | ||
1610 | 1616 | ||
1611 | return 0; | 1617 | return 0; |
1612 | } | 1618 | } |
@@ -2132,3 +2138,41 @@ int omap_hwmod_for_each_by_class(const char *classname, | |||
2132 | return ret; | 2138 | return ret; |
2133 | } | 2139 | } |
2134 | 2140 | ||
2141 | /** | ||
2142 | * omap_hwmod_set_postsetup_state - set the post-_setup() state for this hwmod | ||
2143 | * @oh: struct omap_hwmod * | ||
2144 | * @state: state that _setup() should leave the hwmod in | ||
2145 | * | ||
2146 | * Sets the hwmod state that @oh will enter at the end of _setup() (called by | ||
2147 | * omap_hwmod_late_init()). Only valid to call between calls to | ||
2148 | * omap_hwmod_init() and omap_hwmod_late_init(). Returns 0 upon success or | ||
2149 | * -EINVAL if there is a problem with the arguments or if the hwmod is | ||
2150 | * in the wrong state. | ||
2151 | */ | ||
2152 | int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state) | ||
2153 | { | ||
2154 | int ret; | ||
2155 | |||
2156 | if (!oh) | ||
2157 | return -EINVAL; | ||
2158 | |||
2159 | if (state != _HWMOD_STATE_DISABLED && | ||
2160 | state != _HWMOD_STATE_ENABLED && | ||
2161 | state != _HWMOD_STATE_IDLE) | ||
2162 | return -EINVAL; | ||
2163 | |||
2164 | mutex_lock(&oh->_mutex); | ||
2165 | |||
2166 | if (oh->_state != _HWMOD_STATE_REGISTERED) { | ||
2167 | ret = -EINVAL; | ||
2168 | goto ohsps_unlock; | ||
2169 | } | ||
2170 | |||
2171 | oh->_postsetup_state = state; | ||
2172 | ret = 0; | ||
2173 | |||
2174 | ohsps_unlock: | ||
2175 | mutex_unlock(&oh->_mutex); | ||
2176 | |||
2177 | return ret; | ||
2178 | } | ||
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index d1f1265fc4a6..b445ecdb95b8 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h | |||
@@ -462,6 +462,7 @@ struct omap_hwmod_class { | |||
462 | * @response_lat: device OCP response latency (in interface clock cycles) | 462 | * @response_lat: device OCP response latency (in interface clock cycles) |
463 | * @_int_flags: internal-use hwmod flags | 463 | * @_int_flags: internal-use hwmod flags |
464 | * @_state: internal-use hwmod state | 464 | * @_state: internal-use hwmod state |
465 | * @_postsetup_state: internal-use state to leave the hwmod in after _setup() | ||
465 | * @flags: hwmod flags (documented below) | 466 | * @flags: hwmod flags (documented below) |
466 | * @omap_chip: OMAP chips this hwmod is present on | 467 | * @omap_chip: OMAP chips this hwmod is present on |
467 | * @_mutex: mutex serializing operations on this hwmod | 468 | * @_mutex: mutex serializing operations on this hwmod |
@@ -510,6 +511,7 @@ struct omap_hwmod { | |||
510 | u8 hwmods_cnt; | 511 | u8 hwmods_cnt; |
511 | u8 _int_flags; | 512 | u8 _int_flags; |
512 | u8 _state; | 513 | u8 _state; |
514 | u8 _postsetup_state; | ||
513 | const struct omap_chip_id omap_chip; | 515 | const struct omap_chip_id omap_chip; |
514 | }; | 516 | }; |
515 | 517 | ||
@@ -519,7 +521,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh); | |||
519 | struct omap_hwmod *omap_hwmod_lookup(const char *name); | 521 | struct omap_hwmod *omap_hwmod_lookup(const char *name); |
520 | int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), | 522 | int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), |
521 | void *data); | 523 | void *data); |
522 | int omap_hwmod_late_init(u8 skip_setup_idle); | 524 | int omap_hwmod_late_init(void); |
523 | 525 | ||
524 | int omap_hwmod_enable(struct omap_hwmod *oh); | 526 | int omap_hwmod_enable(struct omap_hwmod *oh); |
525 | int _omap_hwmod_enable(struct omap_hwmod *oh); | 527 | int _omap_hwmod_enable(struct omap_hwmod *oh); |
@@ -566,6 +568,8 @@ int omap_hwmod_for_each_by_class(const char *classname, | |||
566 | void *user), | 568 | void *user), |
567 | void *user); | 569 | void *user); |
568 | 570 | ||
571 | int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state); | ||
572 | |||
569 | /* | 573 | /* |
570 | * Chip variant-specific hwmod init routines - XXX should be converted | 574 | * Chip variant-specific hwmod init routines - XXX should be converted |
571 | * to use initcalls once the initial boot ordering is straightened out | 575 | * to use initcalls once the initial boot ordering is straightened out |