sh: Keep track of allowed sleep modes
authorMagnus Damm <damm@opensource.se>
Fri, 30 Oct 2009 04:24:15 +0000 (04:24 +0000)
committerPaul Mundt <lethal@linux-sh.org>
Fri, 30 Oct 2009 05:37:42 +0000 (14:37 +0900)
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>
arch/sh/include/asm/suspend.h
arch/sh/kernel/cpu/shmobile/cpuidle.c
arch/sh/kernel/cpu/shmobile/pm.c

index 8e2c55dc5fe608de3885d89cc2bce083449f7e70..8eddf236fb85a9fa4e92fb4474f280b5313f0ac9 100644 (file)
@@ -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 */
index 1c504bd972c305fba8684f99c53fd443ecd74c16..83972aa319c28c5d28b2e89f860346cbddf26596 100644 (file)
@@ -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;
 
index cb3d28f2968cf5b1998cc1ef93535dbe9565b1ba..a94dc480f0c1371efd77cb299da987c8bf5bd60c 100644 (file)
@@ -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);