aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
authorKevin Hilman <khilman@ti.com>2012-06-18 14:12:24 -0400
committerPaul Walmsley <paul@pwsan.com>2012-06-18 14:12:24 -0400
commit8f6aa8ee114fb52a425e247e27e271ee35d7d3b3 (patch)
tree10724b6a72f97a9953508eb8e616963b042b5401 /arch/arm/mach-omap2/omap_hwmod.c
parentbaa2607f56f1589eb21c01fe16aa5f5c3f9dad31 (diff)
ARM: OMAP2+: hwmod: use init-time function pointer for wait_target_ready
Rather than using cpu_is* checking at runtime, initialize an SoC specific function pointer for wait_target_ready(). While here, downgrade the BUG() to a WARN_ON() so it gives a noisy warning instead of causing a kernel panic. Signed-off-by: Kevin Hilman <khilman@ti.com> [paul@pwsan.com: convert to use soc_ops function pointers; add kerneldoc; move soc_ops functions to their own section in the code; integrated the _wait_target_ready() function with the OMAP2/OMAP4 variants; renamed the wait_module_ready field to wait_target_ready] Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c115
1 files changed, 66 insertions, 49 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 2b845836f7d..d1f784cd5f0 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -178,6 +178,7 @@
178struct omap_hwmod_soc_ops { 178struct omap_hwmod_soc_ops {
179 void (*enable_module)(struct omap_hwmod *oh); 179 void (*enable_module)(struct omap_hwmod *oh);
180 int (*disable_module)(struct omap_hwmod *oh); 180 int (*disable_module)(struct omap_hwmod *oh);
181 int (*wait_target_ready)(struct omap_hwmod *oh);
181}; 182};
182 183
183/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ 184/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
@@ -1362,53 +1363,6 @@ static int _init_clocks(struct omap_hwmod *oh, void *data)
1362} 1363}
1363 1364
1364/** 1365/**
1365 * _wait_target_ready - wait for a module to leave slave idle
1366 * @oh: struct omap_hwmod *
1367 *
1368 * Wait for a module @oh to leave slave idle. Returns 0 if the module
1369 * does not have an IDLEST bit or if the module successfully leaves
1370 * slave idle; otherwise, pass along the return value of the
1371 * appropriate *_cm*_wait_module_ready() function.
1372 */
1373static int _wait_target_ready(struct omap_hwmod *oh)
1374{
1375 struct omap_hwmod_ocp_if *os;
1376 int ret;
1377
1378 if (!oh)
1379 return -EINVAL;
1380
1381 if (oh->flags & HWMOD_NO_IDLEST)
1382 return 0;
1383
1384 os = _find_mpu_rt_port(oh);
1385 if (!os)
1386 return 0;
1387
1388 /* XXX check module SIDLEMODE */
1389
1390 /* XXX check clock enable states */
1391
1392 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1393 ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
1394 oh->prcm.omap2.idlest_reg_id,
1395 oh->prcm.omap2.idlest_idle_bit);
1396 } else if (cpu_is_omap44xx()) {
1397 if (!oh->clkdm)
1398 return -EINVAL;
1399
1400 ret = omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition,
1401 oh->clkdm->cm_inst,
1402 oh->clkdm->clkdm_offs,
1403 oh->prcm.omap4.clkctrl_offs);
1404 } else {
1405 BUG();
1406 };
1407
1408 return ret;
1409}
1410
1411/**
1412 * _lookup_hardreset - fill register bit info for this hwmod/reset line 1366 * _lookup_hardreset - fill register bit info for this hwmod/reset line
1413 * @oh: struct omap_hwmod * 1367 * @oh: struct omap_hwmod *
1414 * @name: name of the reset line in the context of this hwmod 1368 * @name: name of the reset line in the context of this hwmod
@@ -1826,7 +1780,8 @@ static int _enable(struct omap_hwmod *oh)
1826 if (soc_ops.enable_module) 1780 if (soc_ops.enable_module)
1827 soc_ops.enable_module(oh); 1781 soc_ops.enable_module(oh);
1828 1782
1829 r = _wait_target_ready(oh); 1783 r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
1784 -EINVAL;
1830 if (!r) { 1785 if (!r) {
1831 /* 1786 /*
1832 * Set the clockdomain to HW_AUTO only if the target is ready, 1787 * Set the clockdomain to HW_AUTO only if the target is ready,
@@ -2443,6 +2398,63 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
2443 return 0; 2398 return 0;
2444} 2399}
2445 2400
2401/* Static functions intended only for use in soc_ops field function pointers */
2402
2403/**
2404 * _omap2_wait_target_ready - wait for a module to leave slave idle
2405 * @oh: struct omap_hwmod *
2406 *
2407 * Wait for a module @oh to leave slave idle. Returns 0 if the module
2408 * does not have an IDLEST bit or if the module successfully leaves
2409 * slave idle; otherwise, pass along the return value of the
2410 * appropriate *_cm*_wait_module_ready() function.
2411 */
2412static int _omap2_wait_target_ready(struct omap_hwmod *oh)
2413{
2414 if (!oh)
2415 return -EINVAL;
2416
2417 if (oh->flags & HWMOD_NO_IDLEST)
2418 return 0;
2419
2420 if (!_find_mpu_rt_port(oh))
2421 return 0;
2422
2423 /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
2424
2425 return omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
2426 oh->prcm.omap2.idlest_reg_id,
2427 oh->prcm.omap2.idlest_idle_bit);
2428}
2429
2430/**
2431 * _omap4_wait_target_ready - wait for a module to leave slave idle
2432 * @oh: struct omap_hwmod *
2433 *
2434 * Wait for a module @oh to leave slave idle. Returns 0 if the module
2435 * does not have an IDLEST bit or if the module successfully leaves
2436 * slave idle; otherwise, pass along the return value of the
2437 * appropriate *_cm*_wait_module_ready() function.
2438 */
2439static int _omap4_wait_target_ready(struct omap_hwmod *oh)
2440{
2441 if (!oh || !oh->clkdm)
2442 return -EINVAL;
2443
2444 if (oh->flags & HWMOD_NO_IDLEST)
2445 return 0;
2446
2447 if (!_find_mpu_rt_port(oh))
2448 return 0;
2449
2450 /* XXX check module SIDLEMODE, hardreset status */
2451
2452 return omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition,
2453 oh->clkdm->cm_inst,
2454 oh->clkdm->clkdm_offs,
2455 oh->prcm.omap4.clkctrl_offs);
2456}
2457
2446/* Public functions */ 2458/* Public functions */
2447 2459
2448u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) 2460u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
@@ -3429,9 +3441,14 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
3429 */ 3441 */
3430void __init omap_hwmod_init(void) 3442void __init omap_hwmod_init(void)
3431{ 3443{
3432 if (cpu_is_omap44xx()) { 3444 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
3445 soc_ops.wait_target_ready = _omap2_wait_target_ready;
3446 } else if (cpu_is_omap44xx()) {
3433 soc_ops.enable_module = _omap4_enable_module; 3447 soc_ops.enable_module = _omap4_enable_module;
3434 soc_ops.disable_module = _omap4_disable_module; 3448 soc_ops.disable_module = _omap4_disable_module;
3449 soc_ops.wait_target_ready = _omap4_wait_target_ready;
3450 } else {
3451 WARN(1, "omap_hwmod: unknown SoC type\n");
3435 } 3452 }
3436 3453
3437 inited = true; 3454 inited = true;