* [PATCH 01/10] OMAP3: PM: whitespace cleanup around IO wakeup enable
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
2010-09-15 23:55 ` [PATCH 02/10] OMAP: PM debugfs removing OMAP3 hardcodings Kevin Hilman
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
Cleanup indentation around IO wakeup enable, the '\' terminator is
not required in C when wrapping an expression past end-of-line.
Whitespace change only.
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm34xx.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 7b03426..b5e5bcb 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -385,9 +385,9 @@ void omap_sram_idle(void)
/* Enable IO-PAD and IO-CHAIN wakeups */
per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
- if (omap3_has_io_wakeup() && \
- (per_next_state < PWRDM_POWER_ON ||
- core_next_state < PWRDM_POWER_ON)) {
+ if (omap3_has_io_wakeup() &&
+ (per_next_state < PWRDM_POWER_ON ||
+ core_next_state < PWRDM_POWER_ON)) {
prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
omap3_enable_io_chain();
}
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 02/10] OMAP: PM debugfs removing OMAP3 hardcodings.
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
2010-09-15 23:55 ` [PATCH 01/10] OMAP3: PM: whitespace cleanup around IO wakeup enable Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
2010-09-15 23:55 ` [PATCH 03/10] OMAP3: PM: move device-specific special cases from PM core into CPUidle Kevin Hilman
` (7 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
From: Thara Gopinath <thara@ti.com>
This patch removes omap3 hardcodings from pm-debug.c
so that enabling PM debugfs support does break compilation
for other OMAP's. This is a preparatory patch for supporting
OMAP4 pm entries through PM debugfs.
Signed-off-by: Thara Gopinath <thara@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm-debug.c | 21 ++++++++++++++++-----
arch/arm/mach-omap2/pm34xx.c | 5 -----
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 723b44e..056ff17 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -37,6 +37,10 @@
#include "pm.h"
int omap2_pm_debug;
+u32 enable_off_mode;
+u32 sleep_while_idle;
+u32 wakeup_timer_seconds;
+u32 wakeup_timer_milliseconds;
#define DUMP_PRM_MOD_REG(mod, reg) \
regs[reg_count].name = #mod "." #reg; \
@@ -494,8 +498,10 @@ int pm_dbg_regset_init(int reg_set)
static int pwrdm_suspend_get(void *data, u64 *val)
{
- int ret;
- ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
+ int ret = -EINVAL;
+
+ if (cpu_is_omap34xx())
+ ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
*val = ret;
if (ret >= 0)
@@ -505,7 +511,10 @@ static int pwrdm_suspend_get(void *data, u64 *val)
static int pwrdm_suspend_set(void *data, u64 val)
{
- return omap3_pm_set_suspend_state((struct powerdomain *)data, (int)val);
+ if (cpu_is_omap34xx())
+ return omap3_pm_set_suspend_state(
+ (struct powerdomain *)data, (int)val);
+ return -EINVAL;
}
DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get,
@@ -553,8 +562,10 @@ static int option_set(void *data, u64 val)
*option = val;
- if (option == &enable_off_mode)
- omap3_pm_off_mode_enable(val);
+ if (option == &enable_off_mode) {
+ if (cpu_is_omap34xx())
+ omap3_pm_off_mode_enable(val);
+ }
return 0;
}
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b5e5bcb..429268e 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -55,11 +55,6 @@
#define OMAP343X_TABLE_VALUE_OFFSET 0x30
#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0x32
-u32 enable_off_mode;
-u32 sleep_while_idle;
-u32 wakeup_timer_seconds;
-u32 wakeup_timer_milliseconds;
-
struct power_state {
struct powerdomain *pwrdm;
u32 next_state;
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 03/10] OMAP3: PM: move device-specific special cases from PM core into CPUidle
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
2010-09-15 23:55 ` [PATCH 01/10] OMAP3: PM: whitespace cleanup around IO wakeup enable Kevin Hilman
2010-09-15 23:55 ` [PATCH 02/10] OMAP: PM debugfs removing OMAP3 hardcodings Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
2010-09-21 7:52 ` Paul Walmsley
2010-09-15 23:55 ` [PATCH 04/10] OMAP4: pm.c extensions for OMAP4 support Kevin Hilman
` (6 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
In an effort to simplify the core idle path, move any device-specific
special case handling from the core PM idle path into the CPUidle
pre-idle checking path.
This keeps the core, interrupts-disabled idle path streamlined and
independent of any device-specific handling, and also allows CPUidle
to do the checking only for certain C-states as needed. This patch
has the device checks in place for all states with the CHECK_BM flag,
namely all states >= C2.
This patch was inspired by a similar patch written by Tero Kristo as
part of a larger series to add INACTIVE state support.
Cc: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/cpuidle34xx.c | 50 ++++++++++++++++++++++++++++++++++--
arch/arm/mach-omap2/pm34xx.c | 14 +---------
2 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 3d3d035..0923b82 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -60,7 +60,8 @@ struct omap3_processor_cx {
struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
struct omap3_processor_cx current_cx_state;
-struct powerdomain *mpu_pd, *core_pd;
+struct powerdomain *mpu_pd, *core_pd, *per_pd;
+struct powerdomain *cam_pd;
/*
* The latencies/thresholds for various C states have
@@ -233,14 +234,54 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
struct cpuidle_state *state)
{
struct cpuidle_state *new_state = next_valid_state(dev, state);
+ u32 core_next_state, per_next_state = 0, per_saved_state = 0;
+ u32 cam_state;
+ struct omap3_processor_cx *cx;
+ int ret;
if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
BUG_ON(!dev->safe_state);
new_state = dev->safe_state;
+ goto select_state;
+ }
+
+ cx = cpuidle_get_statedata(state);
+ core_next_state = cx->core_state;
+
+ /*
+ * Prevent idle completely if CAM is active.
+ * CAM does not have wakeup capability in OMAP3.
+ */
+ cam_state = pwrdm_read_pwrst(cam_pd);
+ if (cam_state == PWRDM_POWER_ON) {
+ new_state = dev->safe_state;
+ goto select_state;
}
+ /*
+ * Prevent PER off if CORE is not in retention or off as this
+ * would disable PER wakeups completely.
+ */
+ per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
+ if ((per_next_state == PWRDM_POWER_OFF) &&
+ (core_next_state > PWRDM_POWER_RET)) {
+ per_next_state = PWRDM_POWER_RET;
+ pwrdm_set_next_pwrst(per_pd, per_next_state);
+ }
+
+ /* Are we changing PER target state? */
+ if (per_next_state != per_saved_state)
+ pwrdm_set_next_pwrst(per_pd, per_next_state);
+
+select_state:
dev->last_state = new_state;
- return omap3_enter_idle(dev, new_state);
+ ret = omap3_enter_idle(dev, new_state);
+
+ /* Restore original PER state if it was modified */
+ if (per_next_state != per_saved_state)
+ pwrdm_set_next_pwrst(per_pd, per_saved_state);
+
+ return ret;
}
DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
@@ -328,7 +369,8 @@ void omap_init_power_states(void)
cpuidle_params_table[OMAP3_STATE_C2].threshold;
omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON;
omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON;
- omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
+ omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID |
+ CPUIDLE_FLAG_CHECK_BM;
/* C3 . MPU CSWR + Core inactive */
omap3_power_states[OMAP3_STATE_C3].valid =
@@ -426,6 +468,8 @@ int __init omap3_idle_init(void)
mpu_pd = pwrdm_lookup("mpu_pwrdm");
core_pd = pwrdm_lookup("core_pwrdm");
+ per_pd = pwrdm_lookup("per_pwrdm");
+ cam_pd = pwrdm_lookup("cam_pwrdm");
omap_init_power_states();
cpuidle_register_driver(&omap3_idle_driver);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 429268e..bb2ba1e 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -346,7 +346,6 @@ void omap_sram_idle(void)
int core_next_state = PWRDM_POWER_ON;
int core_prev_state, per_prev_state;
u32 sdrc_pwr = 0;
- int per_state_modified = 0;
if (!_omap_sram_idle)
return;
@@ -391,19 +390,10 @@ void omap_sram_idle(void)
if (per_next_state < PWRDM_POWER_ON) {
omap_uart_prepare_idle(2);
omap2_gpio_prepare_for_idle(per_next_state);
- if (per_next_state == PWRDM_POWER_OFF) {
- if (core_next_state == PWRDM_POWER_ON) {
- per_next_state = PWRDM_POWER_RET;
- pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
- per_state_modified = 1;
- } else
+ if (per_next_state == PWRDM_POWER_OFF)
omap3_per_save_context();
- }
}
- if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
- omap2_clkdm_deny_idle(mpu_pwrdm->pwrdm_clkdms[0]);
-
/* CORE */
if (core_next_state < PWRDM_POWER_ON) {
omap_uart_prepare_idle(0);
@@ -470,8 +460,6 @@ void omap_sram_idle(void)
if (per_prev_state == PWRDM_POWER_OFF)
omap3_per_restore_context();
omap_uart_resume_idle(2);
- if (per_state_modified)
- pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
}
/* Disable IO-PAD and IO-CHAIN wakeup */
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 03/10] OMAP3: PM: move device-specific special cases from PM core into CPUidle
2010-09-15 23:55 ` [PATCH 03/10] OMAP3: PM: move device-specific special cases from PM core into CPUidle Kevin Hilman
@ 2010-09-21 7:52 ` Paul Walmsley
2010-09-21 17:00 ` Kevin Hilman
0 siblings, 1 reply; 16+ messages in thread
From: Paul Walmsley @ 2010-09-21 7:52 UTC (permalink / raw)
To: linux-arm-kernel
Hi Kevin,
On Wed, 15 Sep 2010, Kevin Hilman wrote:
> In an effort to simplify the core idle path, move any device-specific
> special case handling from the core PM idle path into the CPUidle
> pre-idle checking path.
>
> This keeps the core, interrupts-disabled idle path streamlined and
> independent of any device-specific handling, and also allows CPUidle
> to do the checking only for certain C-states as needed. This patch
> has the device checks in place for all states with the CHECK_BM flag,
> namely all states >= C2.
>
> This patch was inspired by a similar patch written by Tero Kristo as
> part of a larger series to add INACTIVE state support.
As with the original patch, I don't quite understand the improvement
here. In particular, this part:
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> index 3d3d035..0923b82 100644
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -233,14 +234,54 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
> struct cpuidle_state *state)
> {
> struct cpuidle_state *new_state = next_valid_state(dev, state);
> + u32 core_next_state, per_next_state = 0, per_saved_state = 0;
> + u32 cam_state;
> + struct omap3_processor_cx *cx;
> + int ret;
>
> if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
> BUG_ON(!dev->safe_state);
> new_state = dev->safe_state;
> + goto select_state;
> + }
> +
> + cx = cpuidle_get_statedata(state);
> + core_next_state = cx->core_state;
> +
> + /*
> + * Prevent idle completely if CAM is active.
> + * CAM does not have wakeup capability in OMAP3.
> + */
> + cam_state = pwrdm_read_pwrst(cam_pd);
> + if (cam_state == PWRDM_POWER_ON) {
> + new_state = dev->safe_state;
> + goto select_state;
> }
>
> + /*
> + * Prevent PER off if CORE is not in retention or off as this
> + * would disable PER wakeups completely.
> + */
> + per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
> + if ((per_next_state == PWRDM_POWER_OFF) &&
> + (core_next_state > PWRDM_POWER_RET)) {
> + per_next_state = PWRDM_POWER_RET;
> + pwrdm_set_next_pwrst(per_pd, per_next_state);
> + }
> +
> + /* Are we changing PER target state? */
> + if (per_next_state != per_saved_state)
> + pwrdm_set_next_pwrst(per_pd, per_next_state);
In this case, the PER / CORE constraints don't have anything to do with
the MPU or CPUIdle, so they don't seem to belong in the CPUIdle code. The
extra comments are certainly nice -- they make it more clear as to what is
going on here -- but maybe those can just be added to pm34xx.c ?
> +
> +select_state:
> dev->last_state = new_state;
> - return omap3_enter_idle(dev, new_state);
> + ret = omap3_enter_idle(dev, new_state);
> +
> + /* Restore original PER state if it was modified */
> + if (per_next_state != per_saved_state)
> + pwrdm_set_next_pwrst(per_pd, per_saved_state);
> +
> + return ret;
> }
>
> DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
> @@ -328,7 +369,8 @@ void omap_init_power_states(void)
> cpuidle_params_table[OMAP3_STATE_C2].threshold;
> omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON;
> omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON;
> - omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
> + omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID |
> + CPUIDLE_FLAG_CHECK_BM;
>
> /* C3 . MPU CSWR + Core inactive */
> omap3_power_states[OMAP3_STATE_C3].valid =
> @@ -426,6 +468,8 @@ int __init omap3_idle_init(void)
>
> mpu_pd = pwrdm_lookup("mpu_pwrdm");
> core_pd = pwrdm_lookup("core_pwrdm");
> + per_pd = pwrdm_lookup("per_pwrdm");
> + cam_pd = pwrdm_lookup("cam_pwrdm");
>
> omap_init_power_states();
> cpuidle_register_driver(&omap3_idle_driver);
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index 429268e..bb2ba1e 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -346,7 +346,6 @@ void omap_sram_idle(void)
> int core_next_state = PWRDM_POWER_ON;
> int core_prev_state, per_prev_state;
> u32 sdrc_pwr = 0;
> - int per_state_modified = 0;
>
> if (!_omap_sram_idle)
> return;
> @@ -391,19 +390,10 @@ void omap_sram_idle(void)
> if (per_next_state < PWRDM_POWER_ON) {
> omap_uart_prepare_idle(2);
> omap2_gpio_prepare_for_idle(per_next_state);
> - if (per_next_state == PWRDM_POWER_OFF) {
> - if (core_next_state == PWRDM_POWER_ON) {
> - per_next_state = PWRDM_POWER_RET;
> - pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
> - per_state_modified = 1;
> - } else
> + if (per_next_state == PWRDM_POWER_OFF)
> omap3_per_save_context();
> - }
> }
>
> - if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
> - omap2_clkdm_deny_idle(mpu_pwrdm->pwrdm_clkdms[0]);
> -
> /* CORE */
> if (core_next_state < PWRDM_POWER_ON) {
> omap_uart_prepare_idle(0);
> @@ -470,8 +460,6 @@ void omap_sram_idle(void)
> if (per_prev_state == PWRDM_POWER_OFF)
> omap3_per_restore_context();
> omap_uart_resume_idle(2);
> - if (per_state_modified)
> - pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
> }
>
> /* Disable IO-PAD and IO-CHAIN wakeup */
> --
> 1.7.2.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
- Paul
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH 03/10] OMAP3: PM: move device-specific special cases from PM core into CPUidle
2010-09-21 7:52 ` Paul Walmsley
@ 2010-09-21 17:00 ` Kevin Hilman
2010-09-23 23:25 ` Paul Walmsley
0 siblings, 1 reply; 16+ messages in thread
From: Kevin Hilman @ 2010-09-21 17:00 UTC (permalink / raw)
To: linux-arm-kernel
Paul Walmsley <paul@pwsan.com> writes:
> Hi Kevin,
>
> On Wed, 15 Sep 2010, Kevin Hilman wrote:
>
>> In an effort to simplify the core idle path, move any device-specific
>> special case handling from the core PM idle path into the CPUidle
>> pre-idle checking path.
>>
>> This keeps the core, interrupts-disabled idle path streamlined and
>> independent of any device-specific handling, and also allows CPUidle
>> to do the checking only for certain C-states as needed. This patch
>> has the device checks in place for all states with the CHECK_BM flag,
>> namely all states >= C2.
>>
>> This patch was inspired by a similar patch written by Tero Kristo as
>> part of a larger series to add INACTIVE state support.
>
> As with the original patch, I don't quite understand the improvement
> here. In particular, this part:
>
>> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
>> index 3d3d035..0923b82 100644
>> --- a/arch/arm/mach-omap2/cpuidle34xx.c
>> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
>> @@ -233,14 +234,54 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
>> struct cpuidle_state *state)
>> {
>> struct cpuidle_state *new_state = next_valid_state(dev, state);
>> + u32 core_next_state, per_next_state = 0, per_saved_state = 0;
>> + u32 cam_state;
>> + struct omap3_processor_cx *cx;
>> + int ret;
>>
>> if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
>> BUG_ON(!dev->safe_state);
>> new_state = dev->safe_state;
>> + goto select_state;
>> + }
>> +
>> + cx = cpuidle_get_statedata(state);
>> + core_next_state = cx->core_state;
>> +
>> + /*
>> + * Prevent idle completely if CAM is active.
>> + * CAM does not have wakeup capability in OMAP3.
>> + */
>> + cam_state = pwrdm_read_pwrst(cam_pd);
>> + if (cam_state == PWRDM_POWER_ON) {
>> + new_state = dev->safe_state;
>> + goto select_state;
>> }
>>
>> + /*
>> + * Prevent PER off if CORE is not in retention or off as this
>> + * would disable PER wakeups completely.
>> + */
>> + per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
>> + if ((per_next_state == PWRDM_POWER_OFF) &&
>> + (core_next_state > PWRDM_POWER_RET)) {
>> + per_next_state = PWRDM_POWER_RET;
>> + pwrdm_set_next_pwrst(per_pd, per_next_state);
>> + }
>> +
>> + /* Are we changing PER target state? */
>> + if (per_next_state != per_saved_state)
>> + pwrdm_set_next_pwrst(per_pd, per_next_state);
>
> In this case, the PER / CORE constraints don't have anything to do with
> the MPU or CPUIdle, so they don't seem to belong in the CPUIdle code. The
> extra comments are certainly nice -- they make it more clear as to what is
> going on here -- but maybe those can just be added to pm34xx.c ?
CPUidle currently manages MPU and CORE powerdomains, so the CORE
constraints seem to make perfect sense here (at least to me.)
The question is probably more about the PER constraints.
The basic goal of this is to streamline the core idle (omap_sram_idle())
to be the minimum streamline idle, and to move all the constraint
checking and activity checking to higher layers (like CPUidle.)
Specifically, I'm working towards moving the device-specific idle
constraints out of the core idle path (omap_sram_idle()) and move them
into higher layers where we're checking for activity etc.
This is just a baby step towards moving the device-idle out of CPUidle
completely to a place where it can be managed by the driver themeselves
using runtime PM or by using constraints instead of these hard-coded
hacks.
Kevin
>> +
>> +select_state:
>> dev->last_state = new_state;
>> - return omap3_enter_idle(dev, new_state);
>> + ret = omap3_enter_idle(dev, new_state);
>> +
>> + /* Restore original PER state if it was modified */
>> + if (per_next_state != per_saved_state)
>> + pwrdm_set_next_pwrst(per_pd, per_saved_state);
>> +
>> + return ret;
>> }
>>
>> DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
>> @@ -328,7 +369,8 @@ void omap_init_power_states(void)
>> cpuidle_params_table[OMAP3_STATE_C2].threshold;
>> omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON;
>> omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON;
>> - omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
>> + omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID |
>> + CPUIDLE_FLAG_CHECK_BM;
>>
>> /* C3 . MPU CSWR + Core inactive */
>> omap3_power_states[OMAP3_STATE_C3].valid =
>> @@ -426,6 +468,8 @@ int __init omap3_idle_init(void)
>>
>> mpu_pd = pwrdm_lookup("mpu_pwrdm");
>> core_pd = pwrdm_lookup("core_pwrdm");
>> + per_pd = pwrdm_lookup("per_pwrdm");
>> + cam_pd = pwrdm_lookup("cam_pwrdm");
>>
>> omap_init_power_states();
>> cpuidle_register_driver(&omap3_idle_driver);
>> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
>> index 429268e..bb2ba1e 100644
>> --- a/arch/arm/mach-omap2/pm34xx.c
>> +++ b/arch/arm/mach-omap2/pm34xx.c
>> @@ -346,7 +346,6 @@ void omap_sram_idle(void)
>> int core_next_state = PWRDM_POWER_ON;
>> int core_prev_state, per_prev_state;
>> u32 sdrc_pwr = 0;
>> - int per_state_modified = 0;
>>
>> if (!_omap_sram_idle)
>> return;
>> @@ -391,19 +390,10 @@ void omap_sram_idle(void)
>> if (per_next_state < PWRDM_POWER_ON) {
>> omap_uart_prepare_idle(2);
>> omap2_gpio_prepare_for_idle(per_next_state);
>> - if (per_next_state == PWRDM_POWER_OFF) {
>> - if (core_next_state == PWRDM_POWER_ON) {
>> - per_next_state = PWRDM_POWER_RET;
>> - pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
>> - per_state_modified = 1;
>> - } else
>> + if (per_next_state == PWRDM_POWER_OFF)
>> omap3_per_save_context();
>> - }
>> }
>>
>> - if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
>> - omap2_clkdm_deny_idle(mpu_pwrdm->pwrdm_clkdms[0]);
>> -
>> /* CORE */
>> if (core_next_state < PWRDM_POWER_ON) {
>> omap_uart_prepare_idle(0);
>> @@ -470,8 +460,6 @@ void omap_sram_idle(void)
>> if (per_prev_state == PWRDM_POWER_OFF)
>> omap3_per_restore_context();
>> omap_uart_resume_idle(2);
>> - if (per_state_modified)
>> - pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
>> }
>>
>> /* Disable IO-PAD and IO-CHAIN wakeup */
>> --
>> 1.7.2.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
>
> - Paul
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH 03/10] OMAP3: PM: move device-specific special cases from PM core into CPUidle
2010-09-21 17:00 ` Kevin Hilman
@ 2010-09-23 23:25 ` Paul Walmsley
2010-09-23 23:47 ` Kevin Hilman
0 siblings, 1 reply; 16+ messages in thread
From: Paul Walmsley @ 2010-09-23 23:25 UTC (permalink / raw)
To: linux-arm-kernel
Hi Kevin
On Tue, 21 Sep 2010, Kevin Hilman wrote:
> Paul Walmsley <paul@pwsan.com> writes:
>
> > On Wed, 15 Sep 2010, Kevin Hilman wrote:
> >
> >> In an effort to simplify the core idle path, move any device-specific
> >> special case handling from the core PM idle path into the CPUidle
> >> pre-idle checking path.
> >
> > As with the original patch, I don't quite understand the improvement
> > here. In particular, this part:
> >
> >> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> >> index 3d3d035..0923b82 100644
> >> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> >> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> >> @@ -233,14 +234,54 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
> >> struct cpuidle_state *state)
> >> {
> >> struct cpuidle_state *new_state = next_valid_state(dev, state);
> >> + u32 core_next_state, per_next_state = 0, per_saved_state = 0;
> >> + u32 cam_state;
> >> + struct omap3_processor_cx *cx;
> >> + int ret;
> >>
> >> if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
> >> BUG_ON(!dev->safe_state);
> >> new_state = dev->safe_state;
> >> + goto select_state;
> >> + }
> >> +
> >> + cx = cpuidle_get_statedata(state);
> >> + core_next_state = cx->core_state;
> >> +
> >> + /*
> >> + * Prevent idle completely if CAM is active.
> >> + * CAM does not have wakeup capability in OMAP3.
> >> + */
> >> + cam_state = pwrdm_read_pwrst(cam_pd);
> >> + if (cam_state == PWRDM_POWER_ON) {
> >> + new_state = dev->safe_state;
> >> + goto select_state;
> >> }
> >>
> >> + /*
> >> + * Prevent PER off if CORE is not in retention or off as this
> >> + * would disable PER wakeups completely.
> >> + */
> >> + per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
> >> + if ((per_next_state == PWRDM_POWER_OFF) &&
> >> + (core_next_state > PWRDM_POWER_RET)) {
> >> + per_next_state = PWRDM_POWER_RET;
> >> + pwrdm_set_next_pwrst(per_pd, per_next_state);
> >> + }
> >> +
> >> + /* Are we changing PER target state? */
> >> + if (per_next_state != per_saved_state)
> >> + pwrdm_set_next_pwrst(per_pd, per_next_state);
> >
> > In this case, the PER / CORE constraints don't have anything to do with
> > the MPU or CPUIdle, so they don't seem to belong in the CPUIdle code. The
> > extra comments are certainly nice -- they make it more clear as to what is
> > going on here -- but maybe those can just be added to pm34xx.c ?
>
> CPUidle currently manages MPU and CORE powerdomains, so the CORE
> constraints seem to make perfect sense here (at least to me.)
I do mean CORE also -- basically, anything that is not the CPU. IMHO
CPUIdle shouldn't manage CORE directly since it's not part of the CPU.
Also since OMAPs have other processors (e.g., DSP, DMA, etc) that can use
the CORE independently of the CPU's power state, it doesn't make sense for
that code to live inside CPUIdle -- probably it should live in some type
of SystemIdle, CORE powerdomain idle or L3 idle. Again IMHO, the C states
should only represent the MPU's idle state.
> The question is probably more about the PER constraints.
>
> The basic goal of this is to streamline the core idle (omap_sram_idle())
> to be the minimum streamline idle, and to move all the constraint
> checking and activity checking to higher layers (like CPUidle.)
> Specifically, I'm working towards moving the device-specific idle
> constraints out of the core idle path (omap_sram_idle()) and move them
> into higher layers where we're checking for activity etc.
>
> This is just a baby step towards moving the device-idle out of CPUidle
> completely to a place where it can be managed by the driver themeselves
> using runtime PM or by using constraints instead of these hard-coded
> hacks.
I agree completely with the goal; it's the implementation that I don't
like ;-) But if you agree with the basic idea, that CORE / PER /
whatever-idle should ultimately go elsewhere, since I don't have time to
come up with a constructive alternative at the moment, would you be
willing to just drop a FIXME comment in that code, near the CAM and the
PER / CORE stuff, that mentions that that code should ultimately be
segmented out into its own idle code?
thanks
- Paul
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH 03/10] OMAP3: PM: move device-specific special cases from PM core into CPUidle
2010-09-23 23:25 ` Paul Walmsley
@ 2010-09-23 23:47 ` Kevin Hilman
2010-09-24 0:16 ` Kevin Hilman
0 siblings, 1 reply; 16+ messages in thread
From: Kevin Hilman @ 2010-09-23 23:47 UTC (permalink / raw)
To: linux-arm-kernel
Paul Walmsley <paul@pwsan.com> writes:
> Hi Kevin
>
> On Tue, 21 Sep 2010, Kevin Hilman wrote:
>
>> Paul Walmsley <paul@pwsan.com> writes:
>>
>> > On Wed, 15 Sep 2010, Kevin Hilman wrote:
>> >
>> >> In an effort to simplify the core idle path, move any device-specific
>> >> special case handling from the core PM idle path into the CPUidle
>> >> pre-idle checking path.
>> >
>> > As with the original patch, I don't quite understand the improvement
>> > here. In particular, this part:
>> >
>> >> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
>> >> index 3d3d035..0923b82 100644
>> >> --- a/arch/arm/mach-omap2/cpuidle34xx.c
>> >> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
>> >> @@ -233,14 +234,54 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
>> >> struct cpuidle_state *state)
>> >> {
>> >> struct cpuidle_state *new_state = next_valid_state(dev, state);
>> >> + u32 core_next_state, per_next_state = 0, per_saved_state = 0;
>> >> + u32 cam_state;
>> >> + struct omap3_processor_cx *cx;
>> >> + int ret;
>> >>
>> >> if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
>> >> BUG_ON(!dev->safe_state);
>> >> new_state = dev->safe_state;
>> >> + goto select_state;
>> >> + }
>> >> +
>> >> + cx = cpuidle_get_statedata(state);
>> >> + core_next_state = cx->core_state;
>> >> +
>> >> + /*
>> >> + * Prevent idle completely if CAM is active.
>> >> + * CAM does not have wakeup capability in OMAP3.
>> >> + */
>> >> + cam_state = pwrdm_read_pwrst(cam_pd);
>> >> + if (cam_state == PWRDM_POWER_ON) {
>> >> + new_state = dev->safe_state;
>> >> + goto select_state;
>> >> }
>> >>
>> >> + /*
>> >> + * Prevent PER off if CORE is not in retention or off as this
>> >> + * would disable PER wakeups completely.
>> >> + */
>> >> + per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
>> >> + if ((per_next_state == PWRDM_POWER_OFF) &&
>> >> + (core_next_state > PWRDM_POWER_RET)) {
>> >> + per_next_state = PWRDM_POWER_RET;
>> >> + pwrdm_set_next_pwrst(per_pd, per_next_state);
>> >> + }
>> >> +
>> >> + /* Are we changing PER target state? */
>> >> + if (per_next_state != per_saved_state)
>> >> + pwrdm_set_next_pwrst(per_pd, per_next_state);
>> >
>> > In this case, the PER / CORE constraints don't have anything to do with
>> > the MPU or CPUIdle, so they don't seem to belong in the CPUIdle code. The
>> > extra comments are certainly nice -- they make it more clear as to what is
>> > going on here -- but maybe those can just be added to pm34xx.c ?
>>
>> CPUidle currently manages MPU and CORE powerdomains, so the CORE
>> constraints seem to make perfect sense here (at least to me.)
>
> I do mean CORE also -- basically, anything that is not the CPU. IMHO
> CPUIdle shouldn't manage CORE directly since it's not part of the CPU.
> Also since OMAPs have other processors (e.g., DSP, DMA, etc) that can use
> the CORE independently of the CPU's power state, it doesn't make sense for
> that code to live inside CPUIdle -- probably it should live in some type
> of SystemIdle, CORE powerdomain idle or L3 idle. Again IMHO, the C states
> should only represent the MPU's idle state.
>
>> The question is probably more about the PER constraints.
>>
>> The basic goal of this is to streamline the core idle (omap_sram_idle())
>> to be the minimum streamline idle, and to move all the constraint
>> checking and activity checking to higher layers (like CPUidle.)
>> Specifically, I'm working towards moving the device-specific idle
>> constraints out of the core idle path (omap_sram_idle()) and move them
>> into higher layers where we're checking for activity etc.
>>
>> This is just a baby step towards moving the device-idle out of CPUidle
>> completely to a place where it can be managed by the driver themeselves
>> using runtime PM or by using constraints instead of these hard-coded
>> hacks.
>
> I agree completely with the goal; it's the implementation that I don't
> like ;-) But if you agree with the basic idea, that CORE / PER /
> whatever-idle should ultimately go elsewhere, since I don't have time to
> come up with a constructive alternative at the moment, would you be
> willing to just drop a FIXME comment in that code, near the CAM and the
> PER / CORE stuff, that mentions that that code should ultimately be
> segmented out into its own idle code?
Absolutely... will do.
Kevin
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH 03/10] OMAP3: PM: move device-specific special cases from PM core into CPUidle
2010-09-23 23:47 ` Kevin Hilman
@ 2010-09-24 0:16 ` Kevin Hilman
0 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-24 0:16 UTC (permalink / raw)
To: linux-arm-kernel
Kevin Hilman <khilman@deeprootsystems.com> writes:
> Paul Walmsley <paul@pwsan.com> writes:
>
>> Hi Kevin
>>
>> On Tue, 21 Sep 2010, Kevin Hilman wrote:
>>
>>> Paul Walmsley <paul@pwsan.com> writes:
>>>
>>> > On Wed, 15 Sep 2010, Kevin Hilman wrote:
>>> >
>>> >> In an effort to simplify the core idle path, move any device-specific
>>> >> special case handling from the core PM idle path into the CPUidle
>>> >> pre-idle checking path.
>>> >
>>> > As with the original patch, I don't quite understand the improvement
>>> > here. In particular, this part:
>>> >
>>> >> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
>>> >> index 3d3d035..0923b82 100644
>>> >> --- a/arch/arm/mach-omap2/cpuidle34xx.c
>>> >> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
>>> >> @@ -233,14 +234,54 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
>>> >> struct cpuidle_state *state)
>>> >> {
>>> >> struct cpuidle_state *new_state = next_valid_state(dev, state);
>>> >> + u32 core_next_state, per_next_state = 0, per_saved_state = 0;
>>> >> + u32 cam_state;
>>> >> + struct omap3_processor_cx *cx;
>>> >> + int ret;
>>> >>
>>> >> if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
>>> >> BUG_ON(!dev->safe_state);
>>> >> new_state = dev->safe_state;
>>> >> + goto select_state;
>>> >> + }
>>> >> +
>>> >> + cx = cpuidle_get_statedata(state);
>>> >> + core_next_state = cx->core_state;
>>> >> +
>>> >> + /*
>>> >> + * Prevent idle completely if CAM is active.
>>> >> + * CAM does not have wakeup capability in OMAP3.
>>> >> + */
>>> >> + cam_state = pwrdm_read_pwrst(cam_pd);
>>> >> + if (cam_state == PWRDM_POWER_ON) {
>>> >> + new_state = dev->safe_state;
>>> >> + goto select_state;
>>> >> }
>>> >>
>>> >> + /*
>>> >> + * Prevent PER off if CORE is not in retention or off as this
>>> >> + * would disable PER wakeups completely.
>>> >> + */
>>> >> + per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
>>> >> + if ((per_next_state == PWRDM_POWER_OFF) &&
>>> >> + (core_next_state > PWRDM_POWER_RET)) {
>>> >> + per_next_state = PWRDM_POWER_RET;
>>> >> + pwrdm_set_next_pwrst(per_pd, per_next_state);
>>> >> + }
>>> >> +
>>> >> + /* Are we changing PER target state? */
>>> >> + if (per_next_state != per_saved_state)
>>> >> + pwrdm_set_next_pwrst(per_pd, per_next_state);
>>> >
>>> > In this case, the PER / CORE constraints don't have anything to do with
>>> > the MPU or CPUIdle, so they don't seem to belong in the CPUIdle code. The
>>> > extra comments are certainly nice -- they make it more clear as to what is
>>> > going on here -- but maybe those can just be added to pm34xx.c ?
>>>
>>> CPUidle currently manages MPU and CORE powerdomains, so the CORE
>>> constraints seem to make perfect sense here (at least to me.)
>>
>> I do mean CORE also -- basically, anything that is not the CPU. IMHO
>> CPUIdle shouldn't manage CORE directly since it's not part of the CPU.
>> Also since OMAPs have other processors (e.g., DSP, DMA, etc) that can use
>> the CORE independently of the CPU's power state, it doesn't make sense for
>> that code to live inside CPUIdle -- probably it should live in some type
>> of SystemIdle, CORE powerdomain idle or L3 idle. Again IMHO, the C states
>> should only represent the MPU's idle state.
>>
>>> The question is probably more about the PER constraints.
>>>
>>> The basic goal of this is to streamline the core idle (omap_sram_idle())
>>> to be the minimum streamline idle, and to move all the constraint
>>> checking and activity checking to higher layers (like CPUidle.)
>>> Specifically, I'm working towards moving the device-specific idle
>>> constraints out of the core idle path (omap_sram_idle()) and move them
>>> into higher layers where we're checking for activity etc.
>>>
>>> This is just a baby step towards moving the device-idle out of CPUidle
>>> completely to a place where it can be managed by the driver themeselves
>>> using runtime PM or by using constraints instead of these hard-coded
>>> hacks.
>>
>> I agree completely with the goal; it's the implementation that I don't
>> like ;-) But if you agree with the basic idea, that CORE / PER /
>> whatever-idle should ultimately go elsewhere, since I don't have time to
>> come up with a constructive alternative at the moment, would you be
>> willing to just drop a FIXME comment in that code, near the CAM and the
>> PER / CORE stuff, that mentions that that code should ultimately be
>> segmented out into its own idle code?
>
> Absolutely... will do.
>
Here's an updated patch, which will be included in the forthcoming
pm-next pull request. I updated the changelog with a 'NOTE' and also
added a FIXME in the code.
Thanks for the feedback Paul.
Kevin
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 04/10] OMAP4: pm.c extensions for OMAP4 support
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
` (2 preceding siblings ...)
2010-09-15 23:55 ` [PATCH 03/10] OMAP3: PM: move device-specific special cases from PM core into CPUidle Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
2010-09-15 23:55 ` [PATCH 05/10] omap: pm-debug: Move common debug code to pm-debug.c Kevin Hilman
` (5 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
From: Thara Gopinath <thara@ti.com>
OMAP4 has an iva device and a dsp devcice where as OMAP2/3
has only an iva device. In this file the iva device in the
system is registered under the name dsp_dev and the API
to retrieve the iva device is omap2_get_dsp_device.
This patch renames the dsp_dev to iva_dev, renames
omap2_get_dsp_device to omap2_get_iva_device,
registers dsp_dev for OMAP4 and adds a new API
omap4_get_dsp_device to retrieve the dep_dev.
Signed-off-by: Thara Gopinath <thara@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm.c | 20 +++++++++++++++-----
arch/arm/plat-omap/include/plat/common.h | 3 ++-
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 68f9f2e..c93921d 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -21,8 +21,9 @@
static struct omap_device_pm_latency *pm_lats;
static struct device *mpu_dev;
-static struct device *dsp_dev;
+static struct device *iva_dev;
static struct device *l3_dev;
+static struct device *dsp_dev;
struct device *omap2_get_mpuss_device(void)
{
@@ -30,10 +31,10 @@ struct device *omap2_get_mpuss_device(void)
return mpu_dev;
}
-struct device *omap2_get_dsp_device(void)
+struct device *omap2_get_iva_device(void)
{
- WARN_ON_ONCE(!dsp_dev);
- return dsp_dev;
+ WARN_ON_ONCE(!iva_dev);
+ return iva_dev;
}
struct device *omap2_get_l3_device(void)
@@ -42,6 +43,13 @@ struct device *omap2_get_l3_device(void)
return l3_dev;
}
+struct device *omap4_get_dsp_device(void)
+{
+ WARN_ON_ONCE(!dsp_dev);
+ return dsp_dev;
+}
+EXPORT_SYMBOL(omap4_get_dsp_device);
+
/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
static int _init_omap_device(char *name, struct device **new_dev)
{
@@ -69,7 +77,9 @@ static int _init_omap_device(char *name, struct device **new_dev)
static void omap2_init_processor_devices(void)
{
_init_omap_device("mpu", &mpu_dev);
- _init_omap_device("iva", &dsp_dev);
+ _init_omap_device("iva", &iva_dev);
+ if (cpu_is_omap44xx())
+ _init_omap_device("dsp", &dsp_dev);
_init_omap_device("l3_main", &l3_dev);
}
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index 9776b41..c45dbb9 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -91,7 +91,8 @@ void omap3_map_io(void);
})
extern struct device *omap2_get_mpuss_device(void);
-extern struct device *omap2_get_dsp_device(void);
+extern struct device *omap2_get_iva_device(void);
extern struct device *omap2_get_l3_device(void);
+extern struct device *omap4_get_dsp_device(void);
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 05/10] omap: pm-debug: Move common debug code to pm-debug.c
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
` (3 preceding siblings ...)
2010-09-15 23:55 ` [PATCH 04/10] OMAP4: pm.c extensions for OMAP4 support Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
2010-09-15 23:55 ` [PATCH 06/10] omap: pm-debug: Enable wakeup_timer_milliseconds debugfs entry Kevin Hilman
` (4 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
This patch moves omap2_pm_wakeup_on_timer() and pm debug entries
form pm34xx.c to pm-debug.c and export it, so that it is available
to other OMAPs
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm-debug.c | 18 ++++++++++++++++++
arch/arm/mach-omap2/pm.h | 2 ++
arch/arm/mach-omap2/pm34xx.c | 18 ------------------
3 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 056ff17..655f9df 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -31,6 +31,7 @@
#include <plat/board.h>
#include <plat/powerdomain.h>
#include <plat/clockdomain.h>
+#include <plat/dmtimer.h>
#include "prm.h"
#include "cm.h"
@@ -353,6 +354,23 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
pwrdm->timer = t;
}
+void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
+{
+ u32 tick_rate, cycles;
+
+ if (!seconds && !milliseconds)
+ return;
+
+ tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
+ cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
+ omap_dm_timer_stop(gptimer_wakeup);
+ omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
+
+ pr_info("PM: Resume timer in %u.%03u secs"
+ " (%d ticks at %d ticks/sec.)\n",
+ seconds, milliseconds, cycles, tick_rate);
+}
+
static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
{
struct seq_file *s = (struct seq_file *)user;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 3de6ece..4fd021f 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -48,9 +48,11 @@ extern struct omap_dm_timer *gptimer_wakeup;
#ifdef CONFIG_PM_DEBUG
extern void omap2_pm_dump(int mode, int resume, unsigned int us);
+extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds);
extern int omap2_pm_debug;
#else
#define omap2_pm_dump(mode, resume, us) do {} while (0);
+#define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0);
#define omap2_pm_debug 0
#endif
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index bb2ba1e..bc24fbd 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -38,7 +38,6 @@
#include <plat/prcm.h>
#include <plat/gpmc.h>
#include <plat/dma.h>
-#include <plat/dmtimer.h>
#include <asm/tlbflush.h>
@@ -550,23 +549,6 @@ out:
#ifdef CONFIG_SUSPEND
static suspend_state_t suspend_state;
-static void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
-{
- u32 tick_rate, cycles;
-
- if (!seconds && !milliseconds)
- return;
-
- tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
- cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
- omap_dm_timer_stop(gptimer_wakeup);
- omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
-
- pr_info("PM: Resume timer in %u.%03u secs"
- " (%d ticks at %d ticks/sec.)\n",
- seconds, milliseconds, cycles, tick_rate);
-}
-
static int omap3_pm_prepare(void)
{
disable_hlt();
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 06/10] omap: pm-debug: Enable wakeup_timer_milliseconds debugfs entry
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
` (4 preceding siblings ...)
2010-09-15 23:55 ` [PATCH 05/10] omap: pm-debug: Move common debug code to pm-debug.c Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
2010-09-15 23:55 ` [PATCH 07/10] omap: pm: Move set_pwrdm_state routine to common pm.c Kevin Hilman
` (3 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
Commit 8e2efde9 added milliseconds suspend wakeup time support but
same interface is not exported through debugfs
This patch enables the debugfs hook for wakeup_timer_milliseconds
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm-debug.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 655f9df..af00c17 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -638,6 +638,9 @@ static int __init pm_dbg_init(void)
&sleep_while_idle, &pm_dbg_option_fops);
(void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d,
&wakeup_timer_seconds, &pm_dbg_option_fops);
+ (void) debugfs_create_file("wakeup_timer_milliseconds",
+ S_IRUGO | S_IWUGO, d, &wakeup_timer_milliseconds,
+ &pm_dbg_option_fops);
pm_dbg_init_done = 1;
return 0;
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 07/10] omap: pm: Move set_pwrdm_state routine to common pm.c
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
` (5 preceding siblings ...)
2010-09-15 23:55 ` [PATCH 06/10] omap: pm-debug: Enable wakeup_timer_milliseconds debugfs entry Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
2010-09-15 23:55 ` [PATCH 08/10] OMAP clockdomain: initialize clockdomain registers when the clockdomain layer starts Kevin Hilman
` (2 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
The set_pwrdm_state() is needed on omap4 as well so move
this routine to common pm.c file so that it's available for omap3/4
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm.c | 50 +++++++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/pm.h | 2 +-
arch/arm/mach-omap2/pm34xx.c | 53 +++--------------------------------------
3 files changed, 55 insertions(+), 50 deletions(-)
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index c93921d..4477d5d 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -18,6 +18,9 @@
#include <plat/omap_device.h>
#include <plat/common.h>
+#include <plat/powerdomain.h>
+#include <plat/clockdomain.h>
+
static struct omap_device_pm_latency *pm_lats;
static struct device *mpu_dev;
@@ -83,6 +86,53 @@ static void omap2_init_processor_devices(void)
_init_omap_device("l3_main", &l3_dev);
}
+/*
+ * This sets pwrdm state (other than mpu & core. Currently only ON &
+ * RET are supported. Function is assuming that clkdm doesn't have
+ * hw_sup mode enabled.
+ */
+int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
+{
+ u32 cur_state;
+ int sleep_switch = 0;
+ int ret = 0;
+
+ if (pwrdm == NULL || IS_ERR(pwrdm))
+ return -EINVAL;
+
+ while (!(pwrdm->pwrsts & (1 << state))) {
+ if (state == PWRDM_POWER_OFF)
+ return ret;
+ state--;
+ }
+
+ cur_state = pwrdm_read_next_pwrst(pwrdm);
+ if (cur_state == state)
+ return ret;
+
+ if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
+ omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+ sleep_switch = 1;
+ pwrdm_wait_transition(pwrdm);
+ }
+
+ ret = pwrdm_set_next_pwrst(pwrdm, state);
+ if (ret) {
+ printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
+ pwrdm->name);
+ goto err;
+ }
+
+ if (sleep_switch) {
+ omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+ pwrdm_wait_transition(pwrdm);
+ pwrdm_state_switch(pwrdm);
+ }
+
+err:
+ return ret;
+}
+
static int __init omap2_common_pm_init(void)
{
omap2_init_processor_devices();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 4fd021f..77770a1 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -20,7 +20,7 @@ extern void *omap3_secure_ram_storage;
extern void omap3_pm_off_mode_enable(int);
extern void omap_sram_idle(void);
extern int omap3_can_sleep(void);
-extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
+extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
extern int omap3_idle_init(void);
struct cpuidle_params {
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index bc24fbd..f5f1dbd 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -483,51 +483,6 @@ int omap3_can_sleep(void)
return 1;
}
-/* This sets pwrdm state (other than mpu & core. Currently only ON &
- * RET are supported. Function is assuming that clkdm doesn't have
- * hw_sup mode enabled. */
-int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
-{
- u32 cur_state;
- int sleep_switch = 0;
- int ret = 0;
-
- if (pwrdm == NULL || IS_ERR(pwrdm))
- return -EINVAL;
-
- while (!(pwrdm->pwrsts & (1 << state))) {
- if (state == PWRDM_POWER_OFF)
- return ret;
- state--;
- }
-
- cur_state = pwrdm_read_next_pwrst(pwrdm);
- if (cur_state == state)
- return ret;
-
- if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
- omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
- sleep_switch = 1;
- pwrdm_wait_transition(pwrdm);
- }
-
- ret = pwrdm_set_next_pwrst(pwrdm, state);
- if (ret) {
- printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
- pwrdm->name);
- goto err;
- }
-
- if (sleep_switch) {
- omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
- pwrdm_wait_transition(pwrdm);
- pwrdm_state_switch(pwrdm);
- }
-
-err:
- return ret;
-}
-
static void omap3_pm_idle(void)
{
local_irq_disable();
@@ -569,7 +524,7 @@ static int omap3_pm_suspend(void)
pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
/* Set ones wanted by suspend */
list_for_each_entry(pwrst, &pwrst_list, node) {
- if (set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
+ if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
goto restore;
if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
goto restore;
@@ -590,7 +545,7 @@ restore:
pwrst->pwrdm->name, pwrst->next_state);
ret = -1;
}
- set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
+ omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
}
if (ret)
printk(KERN_ERR "Could not enter target state in pm_suspend\n");
@@ -939,7 +894,7 @@ void omap3_pm_off_mode_enable(int enable)
list_for_each_entry(pwrst, &pwrst_list, node) {
pwrst->next_state = state;
- set_pwrdm_state(pwrst->pwrdm, state);
+ omap_set_pwrdm_state(pwrst->pwrdm, state);
}
}
@@ -984,7 +939,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
if (pwrdm_has_hdwr_sar(pwrdm))
pwrdm_enable_hdwr_sar(pwrdm);
- return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+ return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
}
/*
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 08/10] OMAP clockdomain: initialize clockdomain registers when the clockdomain layer starts
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
` (6 preceding siblings ...)
2010-09-15 23:55 ` [PATCH 07/10] omap: pm: Move set_pwrdm_state routine to common pm.c Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
2010-09-15 23:55 ` [PATCH 09/10] Revert "OMAP: omap_device: add omap_device_is_valid()" Kevin Hilman
2010-09-15 23:55 ` [PATCH 10/10] OMAP: omap_device: make all devices a child of a new parent device Kevin Hilman
9 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
From: Paul Walmsley <paul@pwsan.com>
When the clockdomain layer initializes, place all clockdomains into
software-supervised mode, and clear all wakeup and sleep dependencies
immediately, rather than waiting for the PM code to do this later.
This fixes a major bug where critical sleep dependencies added by the
hwmod code are cleared during late PM init.
As a side benefit, the _init_{wk,sleep}dep_usecount() functions are no
longer needed, so remove them.
Kevin Hilman <khilman@deeprootsystems.com> did all the really hard work on
this, identifying the problem and finding the bug.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/clockdomain.c | 110 +++++--------------------------------
arch/arm/mach-omap2/pm34xx.c | 3 -
2 files changed, 15 insertions(+), 98 deletions(-)
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 5d80cb8..6fb61b1 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -258,97 +258,6 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
}
-/**
- * _init_wkdep_usecount - initialize wkdep usecounts to match hardware
- * @clkdm: clockdomain to initialize wkdep usecounts
- *
- * Initialize the wakeup dependency usecount variables for clockdomain @clkdm.
- * If a wakeup dependency is present in the hardware, the usecount will be
- * set to 1; otherwise, it will be set to 0. Software should clear all
- * software wakeup dependencies prior to calling this function if it wishes
- * to ensure that all usecounts start at 0. No return value.
- */
-static void _init_wkdep_usecount(struct clockdomain *clkdm)
-{
- u32 v;
- struct clkdm_dep *cd;
-
- if (!clkdm->wkdep_srcs)
- return;
-
- for (cd = clkdm->wkdep_srcs; cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
-
- if (!cd->clkdm && cd->clkdm_name)
- cd->clkdm = _clkdm_lookup(cd->clkdm_name);
-
- if (!cd->clkdm) {
- WARN(!cd->clkdm, "clockdomain: %s: wkdep clkdm %s not "
- "found\n", clkdm->name, cd->clkdm_name);
- continue;
- }
-
- v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs,
- PM_WKDEP,
- (1 << cd->clkdm->dep_bit));
-
- if (v)
- pr_debug("clockdomain: %s: wakeup dependency already "
- "set to wake up when %s wakes\n",
- clkdm->name, cd->clkdm->name);
-
- atomic_set(&cd->wkdep_usecount, (v) ? 1 : 0);
- }
-}
-
-/**
- * _init_sleepdep_usecount - initialize sleepdep usecounts to match hardware
- * @clkdm: clockdomain to initialize sleepdep usecounts
- *
- * Initialize the sleep dependency usecount variables for clockdomain @clkdm.
- * If a sleep dependency is present in the hardware, the usecount will be
- * set to 1; otherwise, it will be set to 0. Software should clear all
- * software sleep dependencies prior to calling this function if it wishes
- * to ensure that all usecounts start at 0. No return value.
- */
-static void _init_sleepdep_usecount(struct clockdomain *clkdm)
-{
- u32 v;
- struct clkdm_dep *cd;
-
- if (!cpu_is_omap34xx())
- return;
-
- if (!clkdm->sleepdep_srcs)
- return;
-
- for (cd = clkdm->sleepdep_srcs; cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
-
- if (!cd->clkdm && cd->clkdm_name)
- cd->clkdm = _clkdm_lookup(cd->clkdm_name);
-
- if (!cd->clkdm) {
- WARN(!cd->clkdm, "clockdomain: %s: sleepdep clkdm %s "
- "not found\n", clkdm->name, cd->clkdm_name);
- continue;
- }
-
- v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP,
- (1 << cd->clkdm->dep_bit));
-
- if (v)
- pr_debug("clockdomain: %s: sleep dependency already "
- "set to prevent from idling until %s "
- "idles\n", clkdm->name, cd->clkdm->name);
-
- atomic_set(&cd->sleepdep_usecount, (v) ? 1 : 0);
- }
-};
-
/* Public functions */
/**
@@ -379,12 +288,17 @@ void clkdm_init(struct clockdomain **clkdms,
_autodep_lookup(autodep);
/*
- * Ensure that the *dep_usecount registers reflect the current
- * state of the PRCM.
+ * Put all clockdomains into software-supervised mode; PM code
+ * should later enable hardware-supervised mode as appropriate
*/
list_for_each_entry(clkdm, &clkdm_list, node) {
- _init_wkdep_usecount(clkdm);
- _init_sleepdep_usecount(clkdm);
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ omap2_clkdm_wakeup(clkdm);
+ else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
+ omap2_clkdm_deny_idle(clkdm);
+
+ clkdm_clear_all_wkdeps(clkdm);
+ clkdm_clear_all_sleepdeps(clkdm);
}
}
@@ -592,6 +506,9 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
if (!omap_chip_is(cd->omap_chip))
continue;
+ if (!cd->clkdm && cd->clkdm_name)
+ cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
/* PRM accesses are slow, so minimize them */
mask |= 1 << cd->clkdm->dep_bit;
atomic_set(&cd->wkdep_usecount, 0);
@@ -752,6 +669,9 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
if (!omap_chip_is(cd->omap_chip))
continue;
+ if (!cd->clkdm && cd->clkdm_name)
+ cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
/* PRM accesses are slow, so minimize them */
mask |= 1 << cd->clkdm->dep_bit;
atomic_set(&cd->sleepdep_usecount, 0);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index f5f1dbd..d2b940c 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -949,9 +949,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
*/
static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
{
- clkdm_clear_all_wkdeps(clkdm);
- clkdm_clear_all_sleepdeps(clkdm);
-
if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
omap2_clkdm_allow_idle(clkdm);
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 09/10] Revert "OMAP: omap_device: add omap_device_is_valid()"
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
` (7 preceding siblings ...)
2010-09-15 23:55 ` [PATCH 08/10] OMAP clockdomain: initialize clockdomain registers when the clockdomain layer starts Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
2010-09-15 23:55 ` [PATCH 10/10] OMAP: omap_device: make all devices a child of a new parent device Kevin Hilman
9 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
This reverts commit 0007122ad85cc36b1c18c0b59344093ca210d206.
The dereference method of checking for a valid omap_device when
wrapping a platform_device is rather unsafe and dangerous.
Instead, a better way of checking for a valid omap-device is
to use a common parent device for all omap_devices, then a check
can simply be made using the device parent. The only user of this
API was the initial version of the runtime PM core for OMAP. This
has now been switched to check device parent, so there are no more
users of this API.
Acked-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/plat-omap/include/plat/omap_device.h | 2 --
arch/arm/plat-omap/omap_device.c | 20 --------------------
2 files changed, 0 insertions(+), 22 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 25cd9ac..bad4c3d 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -62,7 +62,6 @@
*
*/
struct omap_device {
- u32 magic;
struct platform_device pdev;
struct omap_hwmod **hwmods;
struct omap_device_pm_latency *pm_lats;
@@ -82,7 +81,6 @@ int omap_device_shutdown(struct platform_device *pdev);
/* Core code interface */
-bool omap_device_is_valid(struct omap_device *od);
int omap_device_count_resources(struct omap_device *od);
int omap_device_fill_resources(struct omap_device *od, struct resource *res);
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index d2b1609..7f05f49 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -90,12 +90,6 @@
#define USE_WAKEUP_LAT 0
#define IGNORE_WAKEUP_LAT 1
-/*
- * OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device
- * obtained via container_of() is in fact a struct omap_device
- */
-#define OMAP_DEVICE_MAGIC 0xf00dcafe
-
/* Private functions */
/**
@@ -414,8 +408,6 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
od->pm_lats = pm_lats;
od->pm_lats_cnt = pm_lats_cnt;
- od->magic = OMAP_DEVICE_MAGIC;
-
if (is_early_device)
ret = omap_early_device_register(od);
else
@@ -627,18 +619,6 @@ int omap_device_align_pm_lat(struct platform_device *pdev,
}
/**
- * omap_device_is_valid - Check if pointer is a valid omap_device
- * @od: struct omap_device *
- *
- * Return whether struct omap_device pointer @od points to a valid
- * omap_device.
- */
-bool omap_device_is_valid(struct omap_device *od)
-{
- return (od && od->magic == OMAP_DEVICE_MAGIC);
-}
-
-/**
* omap_device_get_pwrdm - return the powerdomain * associated with @od
* @od: struct omap_device *
*
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 10/10] OMAP: omap_device: make all devices a child of a new parent device
2010-09-15 23:55 [PATCH 00/10] OMAP: misc PM queue for 2.6.37 Kevin Hilman
` (8 preceding siblings ...)
2010-09-15 23:55 ` [PATCH 09/10] Revert "OMAP: omap_device: add omap_device_is_valid()" Kevin Hilman
@ 2010-09-15 23:55 ` Kevin Hilman
9 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-09-15 23:55 UTC (permalink / raw)
To: linux-arm-kernel
In order to help differentiate omap_devices from normal
platform_devices, make them all a parent of a new common parent
device.
Then, in order to determine if a platform_device is also an
omap_device, checking the parent is all that is needed.
Users of this feature are the runtime PM core for OMAP, where we need
to know if a device being passed in is an omap_device or not in order
to know whether to call the omap_device API with it.
In addition, all omap_devices will now show up under /sys/devices/omap
instead of /sys/devices/platform
Acked-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/plat-omap/include/plat/omap_device.h | 2 ++
arch/arm/plat-omap/omap_device.c | 12 ++++++++++++
2 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index bad4c3d..28e2d1a 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -36,6 +36,8 @@
#include <plat/omap_hwmod.h>
+extern struct device omap_device_parent;
+
/* omap_device._state values */
#define OMAP_DEVICE_STATE_UNKNOWN 0
#define OMAP_DEVICE_STATE_ENABLED 1
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 7f05f49..8215b1b 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -465,6 +465,7 @@ int omap_device_register(struct omap_device *od)
{
pr_debug("omap_device: %s: registering\n", od->pdev.name);
+ od->pdev.dev.parent = &omap_device_parent;
return platform_device_register(&od->pdev);
}
@@ -737,3 +738,14 @@ int omap_device_enable_clocks(struct omap_device *od)
/* XXX pass along return value here? */
return 0;
}
+
+struct device omap_device_parent = {
+ .init_name = "omap",
+ .parent = &platform_bus,
+};
+
+static int __init omap_device_init(void)
+{
+ return device_register(&omap_device_parent);
+}
+core_initcall(omap_device_init);
--
1.7.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread