summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/sh/include/asm/suspend.h3
-rw-r--r--arch/sh/kernel/cpu/shmobile/cpuidle.c42
-rw-r--r--arch/sh/kernel/cpu/shmobile/pm.c7
3 files changed, 34 insertions, 18 deletions
diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h
index 8e2c55dc5fe6..8eddf236fb85 100644
--- a/arch/sh/include/asm/suspend.h
+++ b/arch/sh/include/asm/suspend.h
@@ -61,6 +61,9 @@ struct sh_sleep_data {
struct sh_sleep_regs data;
};
+/* a bitmap of supported sleep modes (SUSP_SH..) */
+extern unsigned long sh_mobile_sleep_supported;
+
#endif
/* flags passed to assembly suspend code */
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
index 1c504bd972c3..83972aa319c2 100644
--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -87,25 +87,31 @@ void sh_mobile_setup_cpuidle(void)
dev->safe_state = state;
- state = &dev->states[i++];
- snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
- strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN);
- state->exit_latency = 100;
- state->target_residency = 1 * 2;
- state->power_usage = 1;
- state->flags = 0;
- state->flags |= CPUIDLE_FLAG_TIME_VALID;
- state->enter = cpuidle_sleep_enter;
+ if (sh_mobile_sleep_supported & SUSP_SH_SF) {
+ state = &dev->states[i++];
+ snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
+ strncpy(state->desc, "SuperH Sleep Mode [SF]",
+ CPUIDLE_DESC_LEN);
+ state->exit_latency = 100;
+ state->target_residency = 1 * 2;
+ state->power_usage = 1;
+ state->flags = 0;
+ state->flags |= CPUIDLE_FLAG_TIME_VALID;
+ state->enter = cpuidle_sleep_enter;
+ }
- state = &dev->states[i++];
- snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
- strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN);
- state->exit_latency = 2300;
- state->target_residency = 1 * 2;
- state->power_usage = 1;
- state->flags = 0;
- state->flags |= CPUIDLE_FLAG_TIME_VALID;
- state->enter = cpuidle_sleep_enter;
+ if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) {
+ state = &dev->states[i++];
+ snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
+ strncpy(state->desc, "SuperH Mobile Standby Mode [SF]",
+ CPUIDLE_DESC_LEN);
+ state->exit_latency = 2300;
+ state->target_residency = 1 * 2;
+ state->power_usage = 1;
+ state->flags = 0;
+ state->flags |= CPUIDLE_FLAG_TIME_VALID;
+ state->enter = cpuidle_sleep_enter;
+ }
dev->state_count = i;
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c
index cb3d28f2968c..a94dc480f0c1 100644
--- a/arch/sh/kernel/cpu/shmobile/pm.c
+++ b/arch/sh/kernel/cpu/shmobile/pm.c
@@ -67,6 +67,8 @@ extern char sh_mobile_sleep_enter_end;
extern char sh_mobile_sleep_resume_start;
extern char sh_mobile_sleep_resume_end;
+unsigned long sh_mobile_sleep_supported = SUSP_SH_SLEEP;
+
void sh_mobile_register_self_refresh(unsigned long flags,
void *pre_start, void *pre_end,
void *post_start, void *post_end)
@@ -103,10 +105,15 @@ void sh_mobile_register_self_refresh(unsigned long flags,
vp = onchip_mem + 0x600; /* located at interrupt vector */
n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start;
memcpy(vp, &sh_mobile_sleep_resume_start, n);
+
+ sh_mobile_sleep_supported |= flags;
}
static int sh_pm_enter(suspend_state_t state)
{
+ if (!(sh_mobile_sleep_supported & SUSP_MODE_STANDBY_SF))
+ return -ENXIO;
+
local_irq_disable();
set_bl_bit();
sh_mobile_call_standby(SUSP_MODE_STANDBY_SF);