aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2011-11-11 14:01:30 +0900
committerPaul Mundt <lethal@linux-sh.org>2011-11-11 16:49:28 +0900
commitb73b5c493ac001870bd9faf565a61908c82f52d8 (patch)
treee3f370c108793f726d3a9b6118baf4979d63f08d
parent9b49139b34a66907662e0be8efe79316dc63f8e0 (diff)
ARM: mach-shmobile: cpuidle single/global and last_state fixes
The following commits break cpuidle on SH-Mobile ARM: 46bcfad cpuidle: Single/Global registration of idle states e978aa7 cpuidle: Move dev->last_residency update to driver enter routine; remove dev->last_state This patch remedies these issues by up-porting the SH-Mobile code to fit with the above introduced framework changes. It is worth noting that the new code becomes significantly cleaner, so these framework changes are very welcome. At the same time this breakage could probably have been avoided by grepping for "last_state" and "cpuidle_register_driver". Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/arm/mach-shmobile/cpuidle.c52
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h4
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c14
3 files changed, 30 insertions, 40 deletions
diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
index 2e44f11f592..1b2334277e8 100644
--- a/arch/arm/mach-shmobile/cpuidle.c
+++ b/arch/arm/mach-shmobile/cpuidle.c
@@ -26,65 +26,59 @@ void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = {
};
static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
- struct cpuidle_state *state)
+ struct cpuidle_driver *drv,
+ int index)
{
ktime_t before, after;
- int requested_state = state - &dev->states[0];
- dev->last_state = &dev->states[requested_state];
before = ktime_get();
local_irq_disable();
local_fiq_disable();
- shmobile_cpuidle_modes[requested_state]();
+ shmobile_cpuidle_modes[index]();
local_irq_enable();
local_fiq_enable();
after = ktime_get();
- return ktime_to_ns(ktime_sub(after, before)) >> 10;
+ dev->last_residency = ktime_to_ns(ktime_sub(after, before)) >> 10;
+
+ return index;
}
static struct cpuidle_device shmobile_cpuidle_dev;
static struct cpuidle_driver shmobile_cpuidle_driver = {
.name = "shmobile_cpuidle",
.owner = THIS_MODULE,
+ .states[0] = {
+ .name = "C1",
+ .desc = "WFI",
+ .exit_latency = 1,
+ .target_residency = 1 * 2,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ },
+ .safe_state_index = 0, /* C1 */
+ .state_count = 1,
};
-void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
+void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
static int shmobile_cpuidle_init(void)
{
struct cpuidle_device *dev = &shmobile_cpuidle_dev;
- struct cpuidle_state *state;
+ struct cpuidle_driver *drv = &shmobile_cpuidle_driver;
int i;
- cpuidle_register_driver(&shmobile_cpuidle_driver);
-
- for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
- dev->states[i].name[0] = '\0';
- dev->states[i].desc[0] = '\0';
- dev->states[i].enter = shmobile_cpuidle_enter;
- }
-
- i = CPUIDLE_DRIVER_STATE_START;
-
- state = &dev->states[i++];
- snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
- strncpy(state->desc, "WFI", CPUIDLE_DESC_LEN);
- state->exit_latency = 1;
- state->target_residency = 1 * 2;
- state->power_usage = 3;
- state->flags = 0;
- state->flags |= CPUIDLE_FLAG_TIME_VALID;
-
- dev->safe_state = state;
- dev->state_count = i;
+ for (i = 0; i < CPUIDLE_STATE_MAX; i++)
+ drv->states[i].enter = shmobile_cpuidle_enter;
if (shmobile_cpuidle_setup)
- shmobile_cpuidle_setup(dev);
+ shmobile_cpuidle_setup(drv);
+
+ cpuidle_register_driver(drv);
+ dev->state_count = drv->state_count;
cpuidle_register_device(dev);
return 0;
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index c0cdbf997c9..834bd6cd508 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -9,9 +9,9 @@ extern int clk_init(void);
extern void shmobile_handle_irq_intc(struct pt_regs *);
extern void shmobile_handle_irq_gic(struct pt_regs *);
extern struct platform_suspend_ops shmobile_suspend_ops;
-struct cpuidle_device;
+struct cpuidle_driver;
extern void (*shmobile_cpuidle_modes[])(void);
-extern void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
+extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
extern void sh7367_init_irq(void);
extern void sh7367_add_early_devices(void);
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 79612737c5b..0a5b22942fd 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -402,22 +402,18 @@ static void sh7372_setup_a3sm(unsigned long msk, unsigned long msk2)
#ifdef CONFIG_CPU_IDLE
-static void sh7372_cpuidle_setup(struct cpuidle_device *dev)
+static void sh7372_cpuidle_setup(struct cpuidle_driver *drv)
{
- struct cpuidle_state *state;
- int i = dev->state_count;
+ struct cpuidle_state *state = &drv->states[drv->state_count];
- state = &dev->states[i];
snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN);
state->exit_latency = 10;
state->target_residency = 20 + 10;
- state->power_usage = 1; /* perhaps not */
- state->flags = 0;
- state->flags |= CPUIDLE_FLAG_TIME_VALID;
- shmobile_cpuidle_modes[i] = sh7372_enter_core_standby;
+ state->flags = CPUIDLE_FLAG_TIME_VALID;
+ shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby;
- dev->state_count = i + 1;
+ drv->state_count++;
}
static void sh7372_cpuidle_init(void)