diff options
author | Govindraj R <govindraj.raja@ti.com> | 2011-12-16 16:36:58 -0500 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2011-12-16 16:36:58 -0500 |
commit | eceec00914e3a74b94eea832f9e829c3efcea9bc (patch) | |
tree | 1c99d43a7699dc545c24278e8ec58911df5af37c /arch/arm | |
parent | 96dc19fd03303ae1b9292d1f73aa8de597f4a183 (diff) |
ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup
Add API to enable IO pad wakeup capability based on mux pad and
wake_up enable flag available from hwmod_mux initialization.
Use the wakeup_enable flag and enable wakeup capability for the given
pads. Wakeup capability will be enabled/disabled during hwmod idle
transition based on whether wakeup_flag is set or cleared. If the
hwmod is currently idled, and any mux values were changed by
_set_idle_ioring_wakeup(), the SCM PADCTRL registers will be updated.
Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Tested-by: Kevin Hilman <khilman@ti.com>
Reviewed-by: Kevin Hilman <khilman@ti.com>
[paul@pwsan.com: rearranged code to limit indentation; cleaned up
function documentation; removed unused non-static functions; modified
to search all hwmod pads, not just dynamic remuxing ones; modified to
update SCM regs if hwmod is currently idle and any pads have changed]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 207a2ff9a8c4..21ffd8a831c3 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -381,6 +381,51 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle, | |||
381 | } | 381 | } |
382 | 382 | ||
383 | /** | 383 | /** |
384 | * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux | ||
385 | * @oh: struct omap_hwmod * | ||
386 | * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable | ||
387 | * | ||
388 | * Set or clear the I/O pad wakeup flag in the mux entries for the | ||
389 | * hwmod @oh. This function changes the @oh->mux->pads_dynamic array | ||
390 | * in memory. If the hwmod is currently idled, and the new idle | ||
391 | * values don't match the previous ones, this function will also | ||
392 | * update the SCM PADCTRL registers. Otherwise, if the hwmod is not | ||
393 | * currently idled, this function won't touch the hardware: the new | ||
394 | * mux settings are written to the SCM PADCTRL registers when the | ||
395 | * hwmod is idled. No return value. | ||
396 | */ | ||
397 | static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake) | ||
398 | { | ||
399 | struct omap_device_pad *pad; | ||
400 | bool change = false; | ||
401 | u16 prev_idle; | ||
402 | int j; | ||
403 | |||
404 | if (!oh->mux || !oh->mux->enabled) | ||
405 | return; | ||
406 | |||
407 | for (j = 0; j < oh->mux->nr_pads_dynamic; j++) { | ||
408 | pad = oh->mux->pads_dynamic[j]; | ||
409 | |||
410 | if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP)) | ||
411 | continue; | ||
412 | |||
413 | prev_idle = pad->idle; | ||
414 | |||
415 | if (set_wake) | ||
416 | pad->idle |= OMAP_WAKEUP_EN; | ||
417 | else | ||
418 | pad->idle &= ~OMAP_WAKEUP_EN; | ||
419 | |||
420 | if (prev_idle != pad->idle) | ||
421 | change = true; | ||
422 | } | ||
423 | |||
424 | if (change && oh->_state == _HWMOD_STATE_IDLE) | ||
425 | omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); | ||
426 | } | ||
427 | |||
428 | /** | ||
384 | * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware | 429 | * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware |
385 | * @oh: struct omap_hwmod * | 430 | * @oh: struct omap_hwmod * |
386 | * | 431 | * |
@@ -2416,6 +2461,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) | |||
2416 | v = oh->_sysc_cache; | 2461 | v = oh->_sysc_cache; |
2417 | _enable_wakeup(oh, &v); | 2462 | _enable_wakeup(oh, &v); |
2418 | _write_sysconfig(v, oh); | 2463 | _write_sysconfig(v, oh); |
2464 | _set_idle_ioring_wakeup(oh, true); | ||
2419 | spin_unlock_irqrestore(&oh->_lock, flags); | 2465 | spin_unlock_irqrestore(&oh->_lock, flags); |
2420 | 2466 | ||
2421 | return 0; | 2467 | return 0; |
@@ -2446,6 +2492,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) | |||
2446 | v = oh->_sysc_cache; | 2492 | v = oh->_sysc_cache; |
2447 | _disable_wakeup(oh, &v); | 2493 | _disable_wakeup(oh, &v); |
2448 | _write_sysconfig(v, oh); | 2494 | _write_sysconfig(v, oh); |
2495 | _set_idle_ioring_wakeup(oh, false); | ||
2449 | spin_unlock_irqrestore(&oh->_lock, flags); | 2496 | spin_unlock_irqrestore(&oh->_lock, flags); |
2450 | 2497 | ||
2451 | return 0; | 2498 | return 0; |