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