aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power')
-rw-r--r--kernel/power/Kconfig10
-rw-r--r--kernel/power/hibernate.c58
-rw-r--r--kernel/power/main.c1
-rw-r--r--kernel/power/power.h4
-rw-r--r--kernel/power/snapshot.c33
-rw-r--r--kernel/power/suspend.c14
-rw-r--r--kernel/power/user.c5
7 files changed, 79 insertions, 46 deletions
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 6de9a8fc3417..87f4d24b55b0 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -125,12 +125,6 @@ config PM_DEBUG
125 code. This is helpful when debugging and reporting PM bugs, like 125 code. This is helpful when debugging and reporting PM bugs, like
126 suspend support. 126 suspend support.
127 127
128config PM_VERBOSE
129 bool "Verbose Power Management debugging"
130 depends on PM_DEBUG
131 ---help---
132 This option enables verbose messages from the Power Management code.
133
134config PM_ADVANCED_DEBUG 128config PM_ADVANCED_DEBUG
135 bool "Extra PM attributes in sysfs for low-level debugging/testing" 129 bool "Extra PM attributes in sysfs for low-level debugging/testing"
136 depends on PM_DEBUG 130 depends on PM_DEBUG
@@ -229,3 +223,7 @@ config PM_OPP
229 representing individual voltage domains and provides SOC 223 representing individual voltage domains and provides SOC
230 implementations a ready to use framework to manage OPPs. 224 implementations a ready to use framework to manage OPPs.
231 For more information, read <file:Documentation/power/opp.txt> 225 For more information, read <file:Documentation/power/opp.txt>
226
227config PM_RUNTIME_CLK
228 def_bool y
229 depends on PM_RUNTIME && HAVE_CLK
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 50aae660174d..f9bec56d8825 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -272,12 +272,7 @@ static int create_image(int platform_mode)
272 272
273 local_irq_disable(); 273 local_irq_disable();
274 274
275 error = sysdev_suspend(PMSG_FREEZE); 275 error = syscore_suspend();
276 if (!error) {
277 error = syscore_suspend();
278 if (error)
279 sysdev_resume();
280 }
281 if (error) { 276 if (error) {
282 printk(KERN_ERR "PM: Some system devices failed to power down, " 277 printk(KERN_ERR "PM: Some system devices failed to power down, "
283 "aborting hibernation\n"); 278 "aborting hibernation\n");
@@ -302,7 +297,6 @@ static int create_image(int platform_mode)
302 297
303 Power_up: 298 Power_up:
304 syscore_resume(); 299 syscore_resume();
305 sysdev_resume();
306 /* NOTE: dpm_resume_noirq() is just a resume() for devices 300 /* NOTE: dpm_resume_noirq() is just a resume() for devices
307 * that suspended with irqs off ... no overall powerup. 301 * that suspended with irqs off ... no overall powerup.
308 */ 302 */
@@ -333,20 +327,25 @@ static int create_image(int platform_mode)
333 327
334int hibernation_snapshot(int platform_mode) 328int hibernation_snapshot(int platform_mode)
335{ 329{
330 pm_message_t msg = PMSG_RECOVER;
336 int error; 331 int error;
337 332
338 error = platform_begin(platform_mode); 333 error = platform_begin(platform_mode);
339 if (error) 334 if (error)
340 goto Close; 335 goto Close;
341 336
337 error = dpm_prepare(PMSG_FREEZE);
338 if (error)
339 goto Complete_devices;
340
342 /* Preallocate image memory before shutting down devices. */ 341 /* Preallocate image memory before shutting down devices. */
343 error = hibernate_preallocate_memory(); 342 error = hibernate_preallocate_memory();
344 if (error) 343 if (error)
345 goto Close; 344 goto Complete_devices;
346 345
347 suspend_console(); 346 suspend_console();
348 pm_restrict_gfp_mask(); 347 pm_restrict_gfp_mask();
349 error = dpm_suspend_start(PMSG_FREEZE); 348 error = dpm_suspend(PMSG_FREEZE);
350 if (error) 349 if (error)
351 goto Recover_platform; 350 goto Recover_platform;
352 351
@@ -364,13 +363,17 @@ int hibernation_snapshot(int platform_mode)
364 if (error || !in_suspend) 363 if (error || !in_suspend)
365 swsusp_free(); 364 swsusp_free();
366 365
367 dpm_resume_end(in_suspend ? 366 msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE;
368 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 367 dpm_resume(msg);
369 368
370 if (error || !in_suspend) 369 if (error || !in_suspend)
371 pm_restore_gfp_mask(); 370 pm_restore_gfp_mask();
372 371
373 resume_console(); 372 resume_console();
373
374 Complete_devices:
375 dpm_complete(msg);
376
374 Close: 377 Close:
375 platform_end(platform_mode); 378 platform_end(platform_mode);
376 return error; 379 return error;
@@ -409,12 +412,7 @@ static int resume_target_kernel(bool platform_mode)
409 412
410 local_irq_disable(); 413 local_irq_disable();
411 414
412 error = sysdev_suspend(PMSG_QUIESCE); 415 error = syscore_suspend();
413 if (!error) {
414 error = syscore_suspend();
415 if (error)
416 sysdev_resume();
417 }
418 if (error) 416 if (error)
419 goto Enable_irqs; 417 goto Enable_irqs;
420 418
@@ -442,7 +440,6 @@ static int resume_target_kernel(bool platform_mode)
442 touch_softlockup_watchdog(); 440 touch_softlockup_watchdog();
443 441
444 syscore_resume(); 442 syscore_resume();
445 sysdev_resume();
446 443
447 Enable_irqs: 444 Enable_irqs:
448 local_irq_enable(); 445 local_irq_enable();
@@ -528,7 +525,6 @@ int hibernation_platform_enter(void)
528 goto Platform_finish; 525 goto Platform_finish;
529 526
530 local_irq_disable(); 527 local_irq_disable();
531 sysdev_suspend(PMSG_HIBERNATE);
532 syscore_suspend(); 528 syscore_suspend();
533 if (pm_wakeup_pending()) { 529 if (pm_wakeup_pending()) {
534 error = -EAGAIN; 530 error = -EAGAIN;
@@ -541,7 +537,6 @@ int hibernation_platform_enter(void)
541 537
542 Power_up: 538 Power_up:
543 syscore_resume(); 539 syscore_resume();
544 sysdev_resume();
545 local_irq_enable(); 540 local_irq_enable();
546 enable_nonboot_cpus(); 541 enable_nonboot_cpus();
547 542
@@ -982,10 +977,33 @@ static ssize_t image_size_store(struct kobject *kobj, struct kobj_attribute *att
982 977
983power_attr(image_size); 978power_attr(image_size);
984 979
980static ssize_t reserved_size_show(struct kobject *kobj,
981 struct kobj_attribute *attr, char *buf)
982{
983 return sprintf(buf, "%lu\n", reserved_size);
984}
985
986static ssize_t reserved_size_store(struct kobject *kobj,
987 struct kobj_attribute *attr,
988 const char *buf, size_t n)
989{
990 unsigned long size;
991
992 if (sscanf(buf, "%lu", &size) == 1) {
993 reserved_size = size;
994 return n;
995 }
996
997 return -EINVAL;
998}
999
1000power_attr(reserved_size);
1001
985static struct attribute * g[] = { 1002static struct attribute * g[] = {
986 &disk_attr.attr, 1003 &disk_attr.attr,
987 &resume_attr.attr, 1004 &resume_attr.attr,
988 &image_size_attr.attr, 1005 &image_size_attr.attr,
1006 &reserved_size_attr.attr,
989 NULL, 1007 NULL,
990}; 1008};
991 1009
diff --git a/kernel/power/main.c b/kernel/power/main.c
index de9aef8742f4..2981af4ce7cb 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -337,6 +337,7 @@ static int __init pm_init(void)
337 if (error) 337 if (error)
338 return error; 338 return error;
339 hibernate_image_size_init(); 339 hibernate_image_size_init();
340 hibernate_reserved_size_init();
340 power_kobj = kobject_create_and_add("power", NULL); 341 power_kobj = kobject_create_and_add("power", NULL);
341 if (!power_kobj) 342 if (!power_kobj)
342 return -ENOMEM; 343 return -ENOMEM;
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 03634be55f62..9a00a0a26280 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -15,6 +15,7 @@ struct swsusp_info {
15 15
16#ifdef CONFIG_HIBERNATION 16#ifdef CONFIG_HIBERNATION
17/* kernel/power/snapshot.c */ 17/* kernel/power/snapshot.c */
18extern void __init hibernate_reserved_size_init(void);
18extern void __init hibernate_image_size_init(void); 19extern void __init hibernate_image_size_init(void);
19 20
20#ifdef CONFIG_ARCH_HIBERNATION_HEADER 21#ifdef CONFIG_ARCH_HIBERNATION_HEADER
@@ -55,6 +56,7 @@ extern int hibernation_platform_enter(void);
55 56
56#else /* !CONFIG_HIBERNATION */ 57#else /* !CONFIG_HIBERNATION */
57 58
59static inline void hibernate_reserved_size_init(void) {}
58static inline void hibernate_image_size_init(void) {} 60static inline void hibernate_image_size_init(void) {}
59#endif /* !CONFIG_HIBERNATION */ 61#endif /* !CONFIG_HIBERNATION */
60 62
@@ -72,6 +74,8 @@ static struct kobj_attribute _name##_attr = { \
72 74
73/* Preferred image size in bytes (default 500 MB) */ 75/* Preferred image size in bytes (default 500 MB) */
74extern unsigned long image_size; 76extern unsigned long image_size;
77/* Size of memory reserved for drivers (default SPARE_PAGES x PAGE_SIZE) */
78extern unsigned long reserved_size;
75extern int in_suspend; 79extern int in_suspend;
76extern dev_t swsusp_resume_device; 80extern dev_t swsusp_resume_device;
77extern sector_t swsusp_resume_block; 81extern sector_t swsusp_resume_block;
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index ca0aacc24874..ace55889f702 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -41,16 +41,28 @@ static void swsusp_set_page_forbidden(struct page *);
41static void swsusp_unset_page_forbidden(struct page *); 41static void swsusp_unset_page_forbidden(struct page *);
42 42
43/* 43/*
44 * Number of bytes to reserve for memory allocations made by device drivers
45 * from their ->freeze() and ->freeze_noirq() callbacks so that they don't
46 * cause image creation to fail (tunable via /sys/power/reserved_size).
47 */
48unsigned long reserved_size;
49
50void __init hibernate_reserved_size_init(void)
51{
52 reserved_size = SPARE_PAGES * PAGE_SIZE;
53}
54
55/*
44 * Preferred image size in bytes (tunable via /sys/power/image_size). 56 * Preferred image size in bytes (tunable via /sys/power/image_size).
45 * When it is set to N, the image creating code will do its best to 57 * When it is set to N, swsusp will do its best to ensure the image
46 * ensure the image size will not exceed N bytes, but if that is 58 * size will not exceed N bytes, but if that is impossible, it will
47 * impossible, it will try to create the smallest image possible. 59 * try to create the smallest image possible.
48 */ 60 */
49unsigned long image_size; 61unsigned long image_size;
50 62
51void __init hibernate_image_size_init(void) 63void __init hibernate_image_size_init(void)
52{ 64{
53 image_size = (totalram_pages / 3) * PAGE_SIZE; 65 image_size = ((totalram_pages * 2) / 5) * PAGE_SIZE;
54} 66}
55 67
56/* List of PBEs needed for restoring the pages that were allocated before 68/* List of PBEs needed for restoring the pages that were allocated before
@@ -1263,11 +1275,13 @@ static unsigned long minimum_image_size(unsigned long saveable)
1263 * frame in use. We also need a number of page frames to be free during 1275 * frame in use. We also need a number of page frames to be free during
1264 * hibernation for allocations made while saving the image and for device 1276 * hibernation for allocations made while saving the image and for device
1265 * drivers, in case they need to allocate memory from their hibernation 1277 * drivers, in case they need to allocate memory from their hibernation
1266 * callbacks (these two numbers are given by PAGES_FOR_IO and SPARE_PAGES, 1278 * callbacks (these two numbers are given by PAGES_FOR_IO (which is a rough
1267 * respectively, both of which are rough estimates). To make this happen, we 1279 * estimate) and reserverd_size divided by PAGE_SIZE (which is tunable through
1268 * compute the total number of available page frames and allocate at least 1280 * /sys/power/reserved_size, respectively). To make this happen, we compute the
1281 * total number of available page frames and allocate at least
1269 * 1282 *
1270 * ([page frames total] + PAGES_FOR_IO + [metadata pages]) / 2 + 2 * SPARE_PAGES 1283 * ([page frames total] + PAGES_FOR_IO + [metadata pages]) / 2
1284 * + 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
1271 * 1285 *
1272 * of them, which corresponds to the maximum size of a hibernation image. 1286 * of them, which corresponds to the maximum size of a hibernation image.
1273 * 1287 *
@@ -1322,7 +1336,8 @@ int hibernate_preallocate_memory(void)
1322 count -= totalreserve_pages; 1336 count -= totalreserve_pages;
1323 1337
1324 /* Compute the maximum number of saveable pages to leave in memory. */ 1338 /* Compute the maximum number of saveable pages to leave in memory. */
1325 max_size = (count - (size + PAGES_FOR_IO)) / 2 - 2 * SPARE_PAGES; 1339 max_size = (count - (size + PAGES_FOR_IO)) / 2
1340 - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE);
1326 /* Compute the desired number of image pages specified by image_size. */ 1341 /* Compute the desired number of image pages specified by image_size. */
1327 size = DIV_ROUND_UP(image_size, PAGE_SIZE); 1342 size = DIV_ROUND_UP(image_size, PAGE_SIZE);
1328 if (size > max_size) 1343 if (size > max_size)
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 8935369d503a..1c41ba215419 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -163,19 +163,13 @@ static int suspend_enter(suspend_state_t state)
163 arch_suspend_disable_irqs(); 163 arch_suspend_disable_irqs();
164 BUG_ON(!irqs_disabled()); 164 BUG_ON(!irqs_disabled());
165 165
166 error = sysdev_suspend(PMSG_SUSPEND); 166 error = syscore_suspend();
167 if (!error) {
168 error = syscore_suspend();
169 if (error)
170 sysdev_resume();
171 }
172 if (!error) { 167 if (!error) {
173 if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) { 168 if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) {
174 error = suspend_ops->enter(state); 169 error = suspend_ops->enter(state);
175 events_check_enabled = false; 170 events_check_enabled = false;
176 } 171 }
177 syscore_resume(); 172 syscore_resume();
178 sysdev_resume();
179 } 173 }
180 174
181 arch_suspend_enable_irqs(); 175 arch_suspend_enable_irqs();
@@ -216,7 +210,6 @@ int suspend_devices_and_enter(suspend_state_t state)
216 goto Close; 210 goto Close;
217 } 211 }
218 suspend_console(); 212 suspend_console();
219 pm_restrict_gfp_mask();
220 suspend_test_start(); 213 suspend_test_start();
221 error = dpm_suspend_start(PMSG_SUSPEND); 214 error = dpm_suspend_start(PMSG_SUSPEND);
222 if (error) { 215 if (error) {
@@ -227,13 +220,12 @@ int suspend_devices_and_enter(suspend_state_t state)
227 if (suspend_test(TEST_DEVICES)) 220 if (suspend_test(TEST_DEVICES))
228 goto Recover_platform; 221 goto Recover_platform;
229 222
230 suspend_enter(state); 223 error = suspend_enter(state);
231 224
232 Resume_devices: 225 Resume_devices:
233 suspend_test_start(); 226 suspend_test_start();
234 dpm_resume_end(PMSG_RESUME); 227 dpm_resume_end(PMSG_RESUME);
235 suspend_test_finish("resume devices"); 228 suspend_test_finish("resume devices");
236 pm_restore_gfp_mask();
237 resume_console(); 229 resume_console();
238 Close: 230 Close:
239 if (suspend_ops->end) 231 if (suspend_ops->end)
@@ -294,7 +286,9 @@ int enter_state(suspend_state_t state)
294 goto Finish; 286 goto Finish;
295 287
296 pr_debug("PM: Entering %s sleep\n", pm_states[state]); 288 pr_debug("PM: Entering %s sleep\n", pm_states[state]);
289 pm_restrict_gfp_mask();
297 error = suspend_devices_and_enter(state); 290 error = suspend_devices_and_enter(state);
291 pm_restore_gfp_mask();
298 292
299 Finish: 293 Finish:
300 pr_debug("PM: Finishing wakeup.\n"); 294 pr_debug("PM: Finishing wakeup.\n");
diff --git a/kernel/power/user.c b/kernel/power/user.c
index c36c3b9e8a84..7d02d33be699 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -135,8 +135,10 @@ static int snapshot_release(struct inode *inode, struct file *filp)
135 free_basic_memory_bitmaps(); 135 free_basic_memory_bitmaps();
136 data = filp->private_data; 136 data = filp->private_data;
137 free_all_swap_pages(data->swap); 137 free_all_swap_pages(data->swap);
138 if (data->frozen) 138 if (data->frozen) {
139 pm_restore_gfp_mask();
139 thaw_processes(); 140 thaw_processes();
141 }
140 pm_notifier_call_chain(data->mode == O_RDONLY ? 142 pm_notifier_call_chain(data->mode == O_RDONLY ?
141 PM_POST_HIBERNATION : PM_POST_RESTORE); 143 PM_POST_HIBERNATION : PM_POST_RESTORE);
142 atomic_inc(&snapshot_device_available); 144 atomic_inc(&snapshot_device_available);
@@ -379,6 +381,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
379 * PM_HIBERNATION_PREPARE 381 * PM_HIBERNATION_PREPARE
380 */ 382 */
381 error = suspend_devices_and_enter(PM_SUSPEND_MEM); 383 error = suspend_devices_and_enter(PM_SUSPEND_MEM);
384 data->ready = 0;
382 break; 385 break;
383 386
384 case SNAPSHOT_PLATFORM_SUPPORT: 387 case SNAPSHOT_PLATFORM_SUPPORT: