summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2009-10-30 07:24:15 +0300
committerPaul Mundt <lethal@linux-sh.org>2009-10-30 08:37:42 +0300
commit02bf89347c7d6a6aeae64f02536dac038c402fce (patch)
tree33e5f6060eb483a8519e3d20deead91d344948b6
parent323ef8dba67fb7b9c709457bd0374d88cfb8f25f (diff)
downloadlinux-02bf89347c7d6a6aeae64f02536dac038c402fce.tar.xz
sh: Keep track of allowed sleep modes
Add code to keep track of supported sleep modes. This to only export cpuidle modes that are backed by board support code. Also, do not allow suspend-to-ram if sdram board code is missing. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-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);