ARM: OMAP2+: hwmod: Add a new state to handle hwmods left enabled at init
Subsystems (4)
PATCH v2 1/1 ARM: OMAP2+: hwmod: Add a new state to handle hwmods left enabled at init
An hwmod with a 'HWMOD_INIT_NO_IDLE' flag set, is left in enabled state by the hwmod framework post the initial setup. Once a real user of the device (a driver) tries to enable it at a later point, the hwmod framework throws a WARN() about the device being already in enabled state.
Fix this by introducing a new state '_HWMOD_STATE_ENABLED_AT_INIT' to identify such devices/hwmods, so nothing but just a state change to '_HWMOD_STATE_ENABLED' can be done when the device/hwmod is requested to be enabled (the first time) by its driver/user.
A good example of a such a device is an UART used as debug console. The UART module needs to be kept enabled through the boot, until the UART driver takes control of it, for debug prints to appear on the console.
---
changes in v2:
Fixed minor typos, removed stay change, updated comment in header.
arch/arm/mach-omap2/omap_hwmod.c | 15 ++++++++++++++- arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +14 -1
@@ -1441,6 +1441,17 @@ static int _enable(struct omap_hwmod *oh)pr_debug ("omap_hwmod: %s: enabling\n" , oh->name); +/* +* hwmods' with HWMOD_INIT_NO_IDLE flag set, are left +* in enabled state at init. +* Now that someone is really trying to enable them, +* just update the state. +*/ +if (oh->_state == _HWMOD_STATE_ENABLED_AT_INIT) { + oh->_state = _HWMOD_STATE_ENABLED; +return 0 ; + } +if (oh->_state != _HWMOD_STATE_INITIALIZED && oh->_state != _HWMOD_STATE_IDLE && oh->_state != _HWMOD_STATE_DISABLED) {
@@ -1744,8 +1755,10 @@ static int _setup(struct omap_hwmod *oh, void *data)* it should be set by the core code as a runtime flag during startup */ if ((oh->flags &HWMOD_INIT_NO_IDLE ) && - (postsetup_state == _HWMOD_STATE_IDLE)) + (postsetup_state == _HWMOD_STATE_IDLE)) { + oh->_state = _HWMOD_STATE_ENABLED_AT_INIT; postsetup_state = _HWMOD_STATE_ENABLED; + }if (postsetup_state == _HWMOD_STATE_IDLE)_idle (oh);
arch/arm/plat-omap/include/plat/omap_hwmod.h +6 -0
@@ -436,6 +436,12 @@ struct omap_hwmod_omap4_prcm {#define _HWMOD_STATE_ENABLED 4#define _HWMOD_STATE_IDLE 5#define _HWMOD_STATE_DISABLED 6 +/* +* This state signifies the hwmod was left enabled +* after init, by the framework, because of the +* 'HWMOD_INIT_NO_IDLE' flag. +*/ +#define _HWMOD_STATE_ENABLED_AT_INIT 7/** * struct omap_hwmod_class - the type of an IP block
Signature · 1 line
1.7.1
PATCH v2 1/1 ARM: OMAP2+: hwmod: Add a new state to handle hwmods left enabled at init
Hi Rajendra,
Quoted 37 lines · Rajendra Nayak
An hwmod with a '
HWMOD_INIT_NO_IDLE' flag set, is left in enabled state by the hwmod framework post the initial setup. Once a real user of the device (a driver) tries to enable it at a later point, the hwmod framework throws aWARN()about the device being already in enabled state.Fix this by introducing a new state '
_HWMOD_STATE_ENABLED_AT_INIT' to identify such devices/hwmods, so nothing but just a state change to '_HWMOD_STATE_ENABLED' can be done when the device/hwmod is requested to be enabled (the first time) by its driver/user.A good example of a such a device is an UART used as debug console. The UART module needs to be kept enabled through the boot, until the UART driver takes control of it, for debug prints to appear on the console.
Acked-by Kevin Hilman <[email protected]>Acked-by Benoit Cousson <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>---
changes in v2:
Fixed minor typos, removed stay change, updated comment in header.?arch/arm/mach-omap2/omap_hwmod.c ? ? ? ? ? ? | ? 15 ++++++++++++++- ?arch/arm/plat-omap/include/plat/omap_hwmod.h | ? ?6 ++++++ ?2 files changed, 20 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +1
-0@@ -1441,6 +1441,17 @@ static int _enable(struct omap_hwmod *oh) ? ? ? ?pr_debug("omap_hwmod: %s: enabling\n", oh->name); + ? ? ? /*
arch/arm/mach-omap2/omap_hwmod.c static int _enable(struct omap_hwmod *oh) · line 1454
Quoted 10 lines
arch/arm/mach-omap2/omap_hwmod.c +10
-0+? ? ? ?* hwmods' with HWMOD_INIT_NO_IDLE flag set, are left +? ? ? ?* in enabled state at init. +? ? ? ?* Now that someone is really trying to enable them, +? ? ? ?* just update the state. +? ? ? ?*/ + ? ? ? if (oh->_state == _HWMOD_STATE_ENABLED_AT_INIT) { + ? ? ? ? ? ? ? oh->_state = _HWMOD_STATE_ENABLED; + ? ? ? ? ? ? ? return 0; + ? ? ? } +
one issue returning from here without doingomap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
causes hmux->enabled to be false after first _enable (get_sync)
and for first _idle(put/put_sync)
omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
will not happen and will not enable rx_pad wake-up for uart. so this is causing wake-up failures from off mode.
[code_snip]
void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
{
int i;
/* Runtime idling of dynamic pads */
if (state == _HWMOD_STATE_IDLE && hmux->enabled) {
for (i = 0; i < hmux->nr_pads_dynamic; i++) {
struct omap_device_pad *pad = hmux->pads_dynamic[i];
int val = -EINVAL;
val = pad->idle;
omap_mux_write(pad->partition, val,
pad->mux->reg_offset);
}
return;
}
[..]
if (state == _HWMOD_STATE_ENABLED)
hmux->enabled = true;
else
hmux->enabled = false;
}[..]
--
Thanks,
Govindraj.R
PATCH v2 1/1 ARM: OMAP2+: hwmod: Add a new state to handle hwmods left enabled at init
Quoted 54 lines · Govindraj
Hi Rajendra,
Quoted 37 lines · Rajendra Nayak
An hwmod with a '
HWMOD_INIT_NO_IDLE' flag set, is left in enabled state by the hwmod framework post the initial setup. Once a real user of the device (a driver) tries to enable it at a later point, the hwmod framework throws aWARN()about the device being already in enabled state.Fix this by introducing a new state '
_HWMOD_STATE_ENABLED_AT_INIT' to identify such devices/hwmods, so nothing but just a state change to '_HWMOD_STATE_ENABLED' can be done when the device/hwmod is requested to be enabled (the first time) by its driver/user.A good example of a such a device is an UART used as debug console. The UART module needs to be kept enabled through the boot, until the UART driver takes control of it, for debug prints to appear on the console.
Acked-by Kevin Hilman<[email protected]>Acked-by Benoit Cousson<[email protected]>Signed-off-by Rajendra Nayak<[email protected]>---
changes in v2:
Fixed minor typos, removed stay change, updated comment in header.arch/arm/mach-omap2/omap_hwmod.c | 15 ++++++++++++++- arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletions(-)arch/arm/mach-omap2/omap_hwmod.c +1
-0@@ -1441,6 +1441,17 @@ static int _enable(struct omap_hwmod *oh)pr_debug ("omap_hwmod: %s: enabling\n" , oh->name); +/* arch/arm/mach-omap2/omap_hwmod.c static int _enable(struct omap_hwmod *oh) · line 1454
Quoted 10 lines
arch/arm/mach-omap2/omap_hwmod.c +10
-0+* hwmods' with HWMOD_INIT_NO_IDLE flag set, are left +* in enabled state at init. +* Now that someone is really trying to enable them, +* just update the state. +*/ +if (oh->_state == _HWMOD_STATE_ENABLED_AT_INIT) { + oh->_state = _HWMOD_STATE_ENABLED; +return 0 ; + } +one issue returning from here without doing
omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
Quoted 7 lines
causes
hmux->enabledto be false after first_enable(get_sync)and for first
_idle(put/put_sync)
omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
will not happen and will not enablerx_padwake-up for uart. so this is causing wake-up failures from off mode.
Ok, so this looks like is something that happens additionally with a driver-enable, which does not happen as part of the framework-enable (as part of setup).
Thanks for digging it up.
An easy way to fix it would be to handle the muxing along with the state change..
if (oh->_state == _HWMOD_STATE_ENABLED_AT_INIT) {
/*
* If the caller has mux data populated, do the mux'ing
* which wouldn't have been done as part of the _enable()
* done during setup.
*/
if (oh->mux)
omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
oh->_state = _HWMOD_STATE_ENABLED;
return 0;
}Will respin with the changes, and hopefully this should fix the wakeup issues from OFF.