1 /* 2 * kernel/power/main.c - PM subsystem core functionality. 3 * 4 * Copyright (c) 2003 Patrick Mochel 5 * Copyright (c) 2003 Open Source Development Lab 6 * 7 * This file is released under the GPLv2 8 * 9 */ 10 11 #include <linux/module.h> 12 #include <linux/suspend.h> 13 #include <linux/kobject.h> 14 #include <linux/string.h> 15 #include <linux/delay.h> 16 #include <linux/errno.h> 17 #include <linux/init.h> 18 #include <linux/console.h> 19 #include <linux/cpu.h> 20 #include <linux/resume-trace.h> 21 #include <linux/freezer.h> 22 #include <linux/vmstat.h> 23 24 #include "power.h" 25 26 /*This is just an arbitrary number */ 27 #define FREE_PAGE_NUMBER (100) 28 29 DEFINE_MUTEX(pm_mutex); 30 31 struct pm_ops *pm_ops; 32 33 /** 34 * pm_set_ops - Set the global power method table. 35 * @ops: Pointer to ops structure. 36 */ 37 38 void pm_set_ops(struct pm_ops * ops) 39 { 40 mutex_lock(&pm_mutex); 41 pm_ops = ops; 42 mutex_unlock(&pm_mutex); 43 } 44 45 /** 46 * pm_valid_only_mem - generic memory-only valid callback 47 * 48 * pm_ops drivers that implement mem suspend only and only need 49 * to check for that in their .valid callback can use this instead 50 * of rolling their own .valid callback. 51 */ 52 int pm_valid_only_mem(suspend_state_t state) 53 { 54 return state == PM_SUSPEND_MEM; 55 } 56 57 58 static inline void pm_finish(suspend_state_t state) 59 { 60 if (pm_ops->finish) 61 pm_ops->finish(state); 62 } 63 64 /** 65 * suspend_prepare - Do prep work before entering low-power state. 66 * @state: State we're entering. 67 * 68 * This is common code that is called for each state that we're 69 * entering. Allocate a console, stop all processes, then make sure 70 * the platform can enter the requested state. 71 */ 72 73 static int suspend_prepare(suspend_state_t state) 74 { 75 int error; 76 unsigned int free_pages; 77 78 if (!pm_ops || !pm_ops->enter) 79 return -EPERM; 80 81 pm_prepare_console(); 82 83 if (freeze_processes()) { 84 error = -EAGAIN; 85 goto Thaw; 86 } 87 88 if ((free_pages = global_page_state(NR_FREE_PAGES)) 89 < FREE_PAGE_NUMBER) { 90 pr_debug("PM: free some memory\n"); 91 shrink_all_memory(FREE_PAGE_NUMBER - free_pages); 92 if (nr_free_pages() < FREE_PAGE_NUMBER) { 93 error = -ENOMEM; 94 printk(KERN_ERR "PM: No enough memory\n"); 95 goto Thaw; 96 } 97 } 98 99 if (pm_ops->set_target) { 100 error = pm_ops->set_target(state); 101 if (error) 102 goto Thaw; 103 } 104 suspend_console(); 105 error = device_suspend(PMSG_SUSPEND); 106 if (error) { 107 printk(KERN_ERR "Some devices failed to suspend\n"); 108 goto Resume_console; 109 } 110 if (pm_ops->prepare) { 111 if ((error = pm_ops->prepare(state))) 112 goto Resume_devices; 113 } 114 115 error = disable_nonboot_cpus(); 116 if (!error) 117 return 0; 118 119 enable_nonboot_cpus(); 120 pm_finish(state); 121 Resume_devices: 122 device_resume(); 123 Resume_console: 124 resume_console(); 125 Thaw: 126 thaw_processes(); 127 pm_restore_console(); 128 return error; 129 } 130 131 /* default implementation */ 132 void __attribute__ ((weak)) arch_suspend_disable_irqs(void) 133 { 134 local_irq_disable(); 135 } 136 137 /* default implementation */ 138 void __attribute__ ((weak)) arch_suspend_enable_irqs(void) 139 { 140 local_irq_enable(); 141 } 142 143 int suspend_enter(suspend_state_t state) 144 { 145 int error = 0; 146 147 arch_suspend_disable_irqs(); 148 BUG_ON(!irqs_disabled()); 149 150 if ((error = device_power_down(PMSG_SUSPEND))) { 151 printk(KERN_ERR "Some devices failed to power down\n"); 152 goto Done; 153 } 154 error = pm_ops->enter(state); 155 device_power_up(); 156 Done: 157 arch_suspend_enable_irqs(); 158 BUG_ON(irqs_disabled()); 159 return error; 160 } 161 162 163 /** 164 * suspend_finish - Do final work before exiting suspend sequence. 165 * @state: State we're coming out of. 166 * 167 * Call platform code to clean up, restart processes, and free the 168 * console that we've allocated. This is not called for suspend-to-disk. 169 */ 170 171 static void suspend_finish(suspend_state_t state) 172 { 173 enable_nonboot_cpus(); 174 pm_finish(state); 175 device_resume(); 176 resume_console(); 177 thaw_processes(); 178 pm_restore_console(); 179 } 180 181 182 183 184 static const char * const pm_states[PM_SUSPEND_MAX] = { 185 [PM_SUSPEND_STANDBY] = "standby", 186 [PM_SUSPEND_MEM] = "mem", 187 }; 188 189 static inline int valid_state(suspend_state_t state) 190 { 191 /* All states need lowlevel support and need to be valid 192 * to the lowlevel implementation, no valid callback 193 * implies that none are valid. */ 194 if (!pm_ops || !pm_ops->valid || !pm_ops->valid(state)) 195 return 0; 196 return 1; 197 } 198 199 200 /** 201 * enter_state - Do common work of entering low-power state. 202 * @state: pm_state structure for state we're entering. 203 * 204 * Make sure we're the only ones trying to enter a sleep state. Fail 205 * if someone has beat us to it, since we don't want anything weird to 206 * happen when we wake up. 207 * Then, do the setup for suspend, enter the state, and cleaup (after 208 * we've woken up). 209 */ 210 211 static int enter_state(suspend_state_t state) 212 { 213 int error; 214 215 if (!valid_state(state)) 216 return -ENODEV; 217 if (!mutex_trylock(&pm_mutex)) 218 return -EBUSY; 219 220 pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); 221 if ((error = suspend_prepare(state))) 222 goto Unlock; 223 224 pr_debug("PM: Entering %s sleep\n", pm_states[state]); 225 error = suspend_enter(state); 226 227 pr_debug("PM: Finishing wakeup.\n"); 228 suspend_finish(state); 229 Unlock: 230 mutex_unlock(&pm_mutex); 231 return error; 232 } 233 234 235 /** 236 * pm_suspend - Externally visible function for suspending system. 237 * @state: Enumerated value of state to enter. 238 * 239 * Determine whether or not value is within range, get state 240 * structure, and enter (above). 241 */ 242 243 int pm_suspend(suspend_state_t state) 244 { 245 if (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX) 246 return enter_state(state); 247 return -EINVAL; 248 } 249 250 EXPORT_SYMBOL(pm_suspend); 251 252 decl_subsys(power,NULL,NULL); 253 254 255 /** 256 * state - control system power state. 257 * 258 * show() returns what states are supported, which is hard-coded to 259 * 'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and 260 * 'disk' (Suspend-to-Disk). 261 * 262 * store() accepts one of those strings, translates it into the 263 * proper enumerated value, and initiates a suspend transition. 264 */ 265 266 static ssize_t state_show(struct kset *kset, char *buf) 267 { 268 int i; 269 char * s = buf; 270 271 for (i = 0; i < PM_SUSPEND_MAX; i++) { 272 if (pm_states[i] && valid_state(i)) 273 s += sprintf(s,"%s ", pm_states[i]); 274 } 275 #ifdef CONFIG_SOFTWARE_SUSPEND 276 s += sprintf(s, "%s\n", "disk"); 277 #else 278 if (s != buf) 279 /* convert the last space to a newline */ 280 *(s-1) = '\n'; 281 #endif 282 return (s - buf); 283 } 284 285 static ssize_t state_store(struct kset *kset, const char *buf, size_t n) 286 { 287 suspend_state_t state = PM_SUSPEND_STANDBY; 288 const char * const *s; 289 char *p; 290 int error; 291 int len; 292 293 p = memchr(buf, '\n', n); 294 len = p ? p - buf : n; 295 296 /* First, check if we are requested to hibernate */ 297 if (len == 4 && !strncmp(buf, "disk", len)) { 298 error = hibernate(); 299 return error ? error : n; 300 } 301 302 for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) { 303 if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) 304 break; 305 } 306 if (state < PM_SUSPEND_MAX && *s) 307 error = enter_state(state); 308 else 309 error = -EINVAL; 310 return error ? error : n; 311 } 312 313 power_attr(state); 314 315 #ifdef CONFIG_PM_TRACE 316 int pm_trace_enabled; 317 318 static ssize_t pm_trace_show(struct kset *kset, char *buf) 319 { 320 return sprintf(buf, "%d\n", pm_trace_enabled); 321 } 322 323 static ssize_t 324 pm_trace_store(struct kset *kset, const char *buf, size_t n) 325 { 326 int val; 327 328 if (sscanf(buf, "%d", &val) == 1) { 329 pm_trace_enabled = !!val; 330 return n; 331 } 332 return -EINVAL; 333 } 334 335 power_attr(pm_trace); 336 337 static struct attribute * g[] = { 338 &state_attr.attr, 339 &pm_trace_attr.attr, 340 NULL, 341 }; 342 #else 343 static struct attribute * g[] = { 344 &state_attr.attr, 345 NULL, 346 }; 347 #endif /* CONFIG_PM_TRACE */ 348 349 static struct attribute_group attr_group = { 350 .attrs = g, 351 }; 352 353 354 static int __init pm_init(void) 355 { 356 int error = subsystem_register(&power_subsys); 357 if (!error) 358 error = sysfs_create_group(&power_subsys.kobj,&attr_group); 359 return error; 360 } 361 362 core_initcall(pm_init); 363