aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/io.c32
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c82
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h6
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
315static 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
334void __init omap2_init_common_infrastructure(void) 339void __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 */
366void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0, 378void __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 */
1324static int _setup(struct omap_hwmod *oh, void *data) 1321static 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 */
1594int omap_hwmod_late_init(u8 skip_setup_idle) 1603int 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 */
2152int 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
2174ohsps_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);
519struct omap_hwmod *omap_hwmod_lookup(const char *name); 521struct omap_hwmod *omap_hwmod_lookup(const char *name);
520int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), 522int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
521 void *data); 523 void *data);
522int omap_hwmod_late_init(u8 skip_setup_idle); 524int omap_hwmod_late_init(void);
523 525
524int omap_hwmod_enable(struct omap_hwmod *oh); 526int omap_hwmod_enable(struct omap_hwmod *oh);
525int _omap_hwmod_enable(struct omap_hwmod *oh); 527int _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
571int 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