* [RFC 1/2] ARM: OMAP2+: hwmod: Split _init() into _init_early() and _init_late()
2013-07-29 9:12 [RFC 0/2] OMAP2+: Convert hwmod to do clock inits and reset when drivers initialize Rajendra Nayak
@ 2013-07-29 9:12 ` Rajendra Nayak
2013-07-29 9:12 ` [RFC 2/2] ARM: OMAP2+: hwmod: Do the late part of init and setup/reset on first enable Rajendra Nayak
1 sibling, 0 replies; 3+ messages in thread
From: Rajendra Nayak @ 2013-07-29 9:12 UTC (permalink / raw)
To: linux-omap, linux-arm-kernel; +Cc: paul, tony, Rajendra Nayak
Split the _init() function into something that can be done early and
the rest which can be done late (during drivers inits).
This is done in preperation to remove the hwmod dependency to do all
clock inits (which inturn need clockdomain and other frameworks to be
in place) and module resets quite early in boot, and instead do these
on demand when the drivers initialize.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/omap_hwmod.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 7341eff..e49159c 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2415,16 +2415,21 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
* upon success or if the hwmod isn't registered, or -EINVAL upon
* failure.
*/
-static int __init _init(struct omap_hwmod *oh, void *data)
+static int __init _init_early(struct omap_hwmod *oh, void *data)
{
- int r;
-
if (oh->_state != _HWMOD_STATE_REGISTERED)
return 0;
if (oh->class->sysc)
_init_mpu_rt_base(oh, NULL);
+ return 0;
+}
+
+static int __init _init_late(struct omap_hwmod *oh, void *data)
+{
+ int r;
+
r = _init_clocks(oh, NULL);
if (r < 0) {
WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);
@@ -3284,7 +3289,8 @@ int __init omap_hwmod_setup_one(const char *oh_name)
_ensure_mpu_hwmod_is_setup(oh);
- _init(oh, NULL);
+ _init_early(oh, NULL);
+ _init_late(oh, NULL);
_setup(oh, NULL);
return 0;
@@ -3302,7 +3308,8 @@ static int __init omap_hwmod_setup_all(void)
{
_ensure_mpu_hwmod_is_setup(NULL);
- omap_hwmod_for_each(_init, NULL);
+ omap_hwmod_for_each(_init_early, NULL);
+ omap_hwmod_for_each(_init_late, NULL);
omap_hwmod_for_each(_setup, NULL);
return 0;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 3+ messages in thread* [RFC 2/2] ARM: OMAP2+: hwmod: Do the late part of init and setup/reset on first enable
2013-07-29 9:12 [RFC 0/2] OMAP2+: Convert hwmod to do clock inits and reset when drivers initialize Rajendra Nayak
2013-07-29 9:12 ` [RFC 1/2] ARM: OMAP2+: hwmod: Split _init() into _init_early() and _init_late() Rajendra Nayak
@ 2013-07-29 9:12 ` Rajendra Nayak
1 sibling, 0 replies; 3+ messages in thread
From: Rajendra Nayak @ 2013-07-29 9:12 UTC (permalink / raw)
To: linux-omap, linux-arm-kernel; +Cc: paul, tony, Rajendra Nayak
Instead of doing a complete init and setup(including reset) of all modules
early at boot, do it when a module is asked to be enabled the first time.
This should get rid of all the need for having all the rest of PM frameworks
in place quite early at boot, and should also make sure reset happens only
when drivers are initializing the modules.
For the modules which do not have drivers build in, do this as part of a
late initcall.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/omap_hwmod.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index e49159c..7e4d602 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2082,6 +2082,9 @@ static int _enable_preprogram(struct omap_hwmod *oh)
return oh->class->enable_preprogram(oh);
}
+static int _init_late(struct omap_hwmod *oh, void *data);
+static void _setup_iclk_autoidle(struct omap_hwmod *oh);
+
/**
* _enable - enable an omap_hwmod
* @oh: struct omap_hwmod *
@@ -2094,9 +2097,17 @@ static int _enable(struct omap_hwmod *oh)
{
int r;
int hwsup = 0;
+ bool needs_reset;
pr_debug("omap_hwmod: %s: enabling\n", oh->name);
+ if (oh->_state == _HWMOD_STATE_REGISTERED) {
+ _init_late(oh, NULL);
+ _setup_iclk_autoidle(oh);
+ if (!(oh->flags & HWMOD_INIT_NO_RESET))
+ needs_reset = true;
+ }
+
/*
* hwmods with HWMOD_INIT_NO_IDLE flag set are left in enabled
* state at init. Now that someone is really trying to enable
@@ -2200,6 +2211,9 @@ static int _enable(struct omap_hwmod *oh)
clkdm_hwmod_disable(oh->clkdm, oh);
}
+ if (needs_reset)
+ r = _reset(oh);
+
return r;
}
@@ -3309,13 +3323,27 @@ static int __init omap_hwmod_setup_all(void)
_ensure_mpu_hwmod_is_setup(NULL);
omap_hwmod_for_each(_init_early, NULL);
- omap_hwmod_for_each(_init_late, NULL);
- omap_hwmod_for_each(_setup, NULL);
return 0;
}
omap_core_initcall(omap_hwmod_setup_all);
+static int __init omap_hwmod_setup_rest(void)
+{
+ struct omap_hwmod *oh;
+
+ _ensure_mpu_hwmod_is_setup(NULL);
+
+ list_for_each_entry(oh, &omap_hwmod_list, node) {
+ if (oh->_state == _HWMOD_STATE_REGISTERED) {
+ _init_late(oh, NULL);
+ _setup(oh, NULL);
+ }
+ }
+ return 0;
+}
+omap_late_initcall(omap_hwmod_setup_rest);
+
/**
* omap_hwmod_enable - enable an omap_hwmod
* @oh: struct omap_hwmod *
--
1.7.9.5
^ permalink raw reply related [flat|nested] 3+ messages in thread