aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2009-10-30 00:24:15 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-10-30 01:37:42 -0400
commit02bf89347c7d6a6aeae64f02536dac038c402fce (patch)
tree33e5f6060eb483a8519e3d20deead91d344948b6 /arch
parent323ef8dba67fb7b9c709457bd0374d88cfb8f25f (diff)
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>
Diffstat (limited to 'arch')
-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 {
61 struct sh_sleep_regs data; 61 struct sh_sleep_regs data;
62}; 62};
63 63
64/* a bitmap of supported sleep modes (SUSP_SH..) */
65extern unsigned long sh_mobile_sleep_supported;
66
64#endif 67#endif
65 68
66/* flags passed to assembly suspend code */ 69/* 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)
87 87
88 dev->safe_state = state; 88 dev->safe_state = state;
89 89
90 state = &dev->states[i++]; 90 if (sh_mobile_sleep_supported & SUSP_SH_SF) {
91 snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); 91 state = &dev->states[i++];
92 strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN); 92 snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
93 state->exit_latency = 100; 93 strncpy(state->desc, "SuperH Sleep Mode [SF]",
94 state->target_residency = 1 * 2; 94 CPUIDLE_DESC_LEN);
95 state->power_usage = 1; 95 state->exit_latency = 100;
96 state->flags = 0; 96 state->target_residency = 1 * 2;
97 state->flags |= CPUIDLE_FLAG_TIME_VALID; 97 state->power_usage = 1;
98 state->enter = cpuidle_sleep_enter; 98 state->flags = 0;
99 state->flags |= CPUIDLE_FLAG_TIME_VALID;
100 state->enter = cpuidle_sleep_enter;
101 }
99 102
100 state = &dev->states[i++]; 103 if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) {
101 snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); 104 state = &dev->states[i++];
102 strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN); 105 snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
103 state->exit_latency = 2300; 106 strncpy(state->desc, "SuperH Mobile Standby Mode [SF]",
104 state->target_residency = 1 * 2; 107 CPUIDLE_DESC_LEN);
105 state->power_usage = 1; 108 state->exit_latency = 2300;
106 state->flags = 0; 109 state->target_residency = 1 * 2;
107 state->flags |= CPUIDLE_FLAG_TIME_VALID; 110 state->power_usage = 1;
108 state->enter = cpuidle_sleep_enter; 111 state->flags = 0;
112 state->flags |= CPUIDLE_FLAG_TIME_VALID;
113 state->enter = cpuidle_sleep_enter;
114 }
109 115
110 dev->state_count = i; 116 dev->state_count = i;
111 117
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;
67extern char sh_mobile_sleep_resume_start; 67extern char sh_mobile_sleep_resume_start;
68extern char sh_mobile_sleep_resume_end; 68extern char sh_mobile_sleep_resume_end;
69 69
70unsigned long sh_mobile_sleep_supported = SUSP_SH_SLEEP;
71
70void sh_mobile_register_self_refresh(unsigned long flags, 72void sh_mobile_register_self_refresh(unsigned long flags,
71 void *pre_start, void *pre_end, 73 void *pre_start, void *pre_end,
72 void *post_start, void *post_end) 74 void *post_start, void *post_end)
@@ -103,10 +105,15 @@ void sh_mobile_register_self_refresh(unsigned long flags,
103 vp = onchip_mem + 0x600; /* located at interrupt vector */ 105 vp = onchip_mem + 0x600; /* located at interrupt vector */
104 n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start; 106 n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start;
105 memcpy(vp, &sh_mobile_sleep_resume_start, n); 107 memcpy(vp, &sh_mobile_sleep_resume_start, n);
108
109 sh_mobile_sleep_supported |= flags;
106} 110}
107 111
108static int sh_pm_enter(suspend_state_t state) 112static int sh_pm_enter(suspend_state_t state)
109{ 113{
114 if (!(sh_mobile_sleep_supported & SUSP_MODE_STANDBY_SF))
115 return -ENXIO;
116
110 local_irq_disable(); 117 local_irq_disable();
111 set_bl_bit(); 118 set_bl_bit();
112 sh_mobile_call_standby(SUSP_MODE_STANDBY_SF); 119 sh_mobile_call_standby(SUSP_MODE_STANDBY_SF);