Commit 38dc63459f185795b24a39f3f4921a433ea9980b
Exists in
master
and in
20 other branches
Merge branch 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6
* 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6: PM: Remove some debug messages producing too much noise PM: Fix warning on suspend errors PM / Hibernate: Add newline to load_image() fail path PM / Hibernate: Fix error handling in save_image() PM / Hibernate: Fix blkdev refleaks PM / yenta: Split resume into early and late parts (rev. 4)
Showing 7 changed files Side-by-side Diff
drivers/base/power/main.c
drivers/base/power/runtime.c
... | ... | @@ -51,8 +51,6 @@ |
51 | 51 | { |
52 | 52 | int retval = 0; |
53 | 53 | |
54 | - dev_dbg(dev, "__pm_runtime_idle()!\n"); | |
55 | - | |
56 | 54 | if (dev->power.runtime_error) |
57 | 55 | retval = -EINVAL; |
58 | 56 | else if (dev->power.idle_notification) |
... | ... | @@ -93,8 +91,6 @@ |
93 | 91 | wake_up_all(&dev->power.wait_queue); |
94 | 92 | |
95 | 93 | out: |
96 | - dev_dbg(dev, "__pm_runtime_idle() returns %d!\n", retval); | |
97 | - | |
98 | 94 | return retval; |
99 | 95 | } |
100 | 96 |
drivers/pcmcia/cs.c
... | ... | @@ -98,10 +98,13 @@ |
98 | 98 | * These functions check for the appropriate struct pcmcia_soket arrays, |
99 | 99 | * and pass them to the low-level functions pcmcia_{suspend,resume}_socket |
100 | 100 | */ |
101 | +static int socket_early_resume(struct pcmcia_socket *skt); | |
102 | +static int socket_late_resume(struct pcmcia_socket *skt); | |
101 | 103 | static int socket_resume(struct pcmcia_socket *skt); |
102 | 104 | static int socket_suspend(struct pcmcia_socket *skt); |
103 | 105 | |
104 | -int pcmcia_socket_dev_suspend(struct device *dev) | |
106 | +static void pcmcia_socket_dev_run(struct device *dev, | |
107 | + int (*cb)(struct pcmcia_socket *)) | |
105 | 108 | { |
106 | 109 | struct pcmcia_socket *socket; |
107 | 110 | |
108 | 111 | |
109 | 112 | |
110 | 113 | |
111 | 114 | |
112 | 115 | |
113 | 116 | |
... | ... | @@ -110,29 +113,34 @@ |
110 | 113 | if (socket->dev.parent != dev) |
111 | 114 | continue; |
112 | 115 | mutex_lock(&socket->skt_mutex); |
113 | - socket_suspend(socket); | |
116 | + cb(socket); | |
114 | 117 | mutex_unlock(&socket->skt_mutex); |
115 | 118 | } |
116 | 119 | up_read(&pcmcia_socket_list_rwsem); |
120 | +} | |
117 | 121 | |
122 | +int pcmcia_socket_dev_suspend(struct device *dev) | |
123 | +{ | |
124 | + pcmcia_socket_dev_run(dev, socket_suspend); | |
118 | 125 | return 0; |
119 | 126 | } |
120 | 127 | EXPORT_SYMBOL(pcmcia_socket_dev_suspend); |
121 | 128 | |
122 | -int pcmcia_socket_dev_resume(struct device *dev) | |
129 | +void pcmcia_socket_dev_early_resume(struct device *dev) | |
123 | 130 | { |
124 | - struct pcmcia_socket *socket; | |
131 | + pcmcia_socket_dev_run(dev, socket_early_resume); | |
132 | +} | |
133 | +EXPORT_SYMBOL(pcmcia_socket_dev_early_resume); | |
125 | 134 | |
126 | - down_read(&pcmcia_socket_list_rwsem); | |
127 | - list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { | |
128 | - if (socket->dev.parent != dev) | |
129 | - continue; | |
130 | - mutex_lock(&socket->skt_mutex); | |
131 | - socket_resume(socket); | |
132 | - mutex_unlock(&socket->skt_mutex); | |
133 | - } | |
134 | - up_read(&pcmcia_socket_list_rwsem); | |
135 | +void pcmcia_socket_dev_late_resume(struct device *dev) | |
136 | +{ | |
137 | + pcmcia_socket_dev_run(dev, socket_late_resume); | |
138 | +} | |
139 | +EXPORT_SYMBOL(pcmcia_socket_dev_late_resume); | |
135 | 140 | |
141 | +int pcmcia_socket_dev_resume(struct device *dev) | |
142 | +{ | |
143 | + pcmcia_socket_dev_run(dev, socket_resume); | |
136 | 144 | return 0; |
137 | 145 | } |
138 | 146 | EXPORT_SYMBOL(pcmcia_socket_dev_resume); |
139 | 147 | |
140 | 148 | |
141 | 149 | |
142 | 150 | |
... | ... | @@ -546,29 +554,24 @@ |
546 | 554 | return 0; |
547 | 555 | } |
548 | 556 | |
549 | -/* | |
550 | - * Resume a socket. If a card is present, verify its CIS against | |
551 | - * our cached copy. If they are different, the card has been | |
552 | - * replaced, and we need to tell the drivers. | |
553 | - */ | |
554 | -static int socket_resume(struct pcmcia_socket *skt) | |
557 | +static int socket_early_resume(struct pcmcia_socket *skt) | |
555 | 558 | { |
556 | - int ret; | |
557 | - | |
558 | - if (!(skt->state & SOCKET_SUSPEND)) | |
559 | - return -EBUSY; | |
560 | - | |
561 | 559 | skt->socket = dead_socket; |
562 | 560 | skt->ops->init(skt); |
563 | 561 | skt->ops->set_socket(skt, &skt->socket); |
562 | + if (skt->state & SOCKET_PRESENT) | |
563 | + skt->resume_status = socket_setup(skt, resume_delay); | |
564 | + return 0; | |
565 | +} | |
564 | 566 | |
567 | +static int socket_late_resume(struct pcmcia_socket *skt) | |
568 | +{ | |
565 | 569 | if (!(skt->state & SOCKET_PRESENT)) { |
566 | 570 | skt->state &= ~SOCKET_SUSPEND; |
567 | 571 | return socket_insert(skt); |
568 | 572 | } |
569 | 573 | |
570 | - ret = socket_setup(skt, resume_delay); | |
571 | - if (ret == 0) { | |
574 | + if (skt->resume_status == 0) { | |
572 | 575 | /* |
573 | 576 | * FIXME: need a better check here for cardbus cards. |
574 | 577 | */ |
... | ... | @@ -594,6 +597,20 @@ |
594 | 597 | skt->state &= ~SOCKET_SUSPEND; |
595 | 598 | |
596 | 599 | return 0; |
600 | +} | |
601 | + | |
602 | +/* | |
603 | + * Resume a socket. If a card is present, verify its CIS against | |
604 | + * our cached copy. If they are different, the card has been | |
605 | + * replaced, and we need to tell the drivers. | |
606 | + */ | |
607 | +static int socket_resume(struct pcmcia_socket *skt) | |
608 | +{ | |
609 | + if (!(skt->state & SOCKET_SUSPEND)) | |
610 | + return -EBUSY; | |
611 | + | |
612 | + socket_early_resume(skt); | |
613 | + return socket_late_resume(skt); | |
597 | 614 | } |
598 | 615 | |
599 | 616 | static void socket_remove(struct pcmcia_socket *skt) |
drivers/pcmcia/yenta_socket.c
... | ... | @@ -1275,16 +1275,26 @@ |
1275 | 1275 | if (socket->type && socket->type->restore_state) |
1276 | 1276 | socket->type->restore_state(socket); |
1277 | 1277 | |
1278 | - return pcmcia_socket_dev_resume(dev); | |
1278 | + pcmcia_socket_dev_early_resume(dev); | |
1279 | + return 0; | |
1279 | 1280 | } |
1280 | 1281 | |
1282 | +static int yenta_dev_resume(struct device *dev) | |
1283 | +{ | |
1284 | + pcmcia_socket_dev_late_resume(dev); | |
1285 | + return 0; | |
1286 | +} | |
1287 | + | |
1281 | 1288 | static struct dev_pm_ops yenta_pm_ops = { |
1282 | 1289 | .suspend_noirq = yenta_dev_suspend_noirq, |
1283 | 1290 | .resume_noirq = yenta_dev_resume_noirq, |
1291 | + .resume = yenta_dev_resume, | |
1284 | 1292 | .freeze_noirq = yenta_dev_suspend_noirq, |
1285 | 1293 | .thaw_noirq = yenta_dev_resume_noirq, |
1294 | + .thaw = yenta_dev_resume, | |
1286 | 1295 | .poweroff_noirq = yenta_dev_suspend_noirq, |
1287 | 1296 | .restore_noirq = yenta_dev_resume_noirq, |
1297 | + .restore = yenta_dev_resume, | |
1288 | 1298 | }; |
1289 | 1299 | |
1290 | 1300 | #define YENTA_PM_OPS (¥ta_pm_ops) |
include/pcmcia/ss.h
... | ... | @@ -262,6 +262,8 @@ |
262 | 262 | struct device dev; |
263 | 263 | /* data internal to the socket driver */ |
264 | 264 | void *driver_data; |
265 | + /* status of the card during resume from a system sleep state */ | |
266 | + int resume_status; | |
265 | 267 | }; |
266 | 268 | |
267 | 269 | |
... | ... | @@ -280,6 +282,8 @@ |
280 | 282 | |
281 | 283 | /* socket drivers are expected to use these callbacks in their .drv struct */ |
282 | 284 | extern int pcmcia_socket_dev_suspend(struct device *dev); |
285 | +extern void pcmcia_socket_dev_early_resume(struct device *dev); | |
286 | +extern void pcmcia_socket_dev_late_resume(struct device *dev); | |
283 | 287 | extern int pcmcia_socket_dev_resume(struct device *dev); |
284 | 288 | |
285 | 289 | /* socket drivers use this callback in their IRQ handler */ |
kernel/power/hibernate.c
... | ... | @@ -693,21 +693,22 @@ |
693 | 693 | /* The snapshot device should not be opened while we're running */ |
694 | 694 | if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { |
695 | 695 | error = -EBUSY; |
696 | + swsusp_close(FMODE_READ); | |
696 | 697 | goto Unlock; |
697 | 698 | } |
698 | 699 | |
699 | 700 | pm_prepare_console(); |
700 | 701 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); |
701 | 702 | if (error) |
702 | - goto Finish; | |
703 | + goto close_finish; | |
703 | 704 | |
704 | 705 | error = usermodehelper_disable(); |
705 | 706 | if (error) |
706 | - goto Finish; | |
707 | + goto close_finish; | |
707 | 708 | |
708 | 709 | error = create_basic_memory_bitmaps(); |
709 | 710 | if (error) |
710 | - goto Finish; | |
711 | + goto close_finish; | |
711 | 712 | |
712 | 713 | pr_debug("PM: Preparing processes for restore.\n"); |
713 | 714 | error = prepare_processes(); |
... | ... | @@ -719,6 +720,7 @@ |
719 | 720 | pr_debug("PM: Reading hibernation image.\n"); |
720 | 721 | |
721 | 722 | error = swsusp_read(&flags); |
723 | + swsusp_close(FMODE_READ); | |
722 | 724 | if (!error) |
723 | 725 | hibernation_restore(flags & SF_PLATFORM_MODE); |
724 | 726 | |
... | ... | @@ -737,6 +739,9 @@ |
737 | 739 | mutex_unlock(&pm_mutex); |
738 | 740 | pr_debug("PM: Resume from disk failed.\n"); |
739 | 741 | return error; |
742 | +close_finish: | |
743 | + swsusp_close(FMODE_READ); | |
744 | + goto Finish; | |
740 | 745 | } |
741 | 746 | |
742 | 747 | late_initcall(software_resume); |
kernel/power/swap.c
... | ... | @@ -314,7 +314,6 @@ |
314 | 314 | { |
315 | 315 | unsigned int m; |
316 | 316 | int ret; |
317 | - int error = 0; | |
318 | 317 | int nr_pages; |
319 | 318 | int err2; |
320 | 319 | struct bio *bio; |
321 | 320 | |
322 | 321 | |
323 | 322 | |
324 | 323 | |
... | ... | @@ -329,26 +328,27 @@ |
329 | 328 | nr_pages = 0; |
330 | 329 | bio = NULL; |
331 | 330 | do_gettimeofday(&start); |
332 | - do { | |
331 | + while (1) { | |
333 | 332 | ret = snapshot_read_next(snapshot, PAGE_SIZE); |
334 | - if (ret > 0) { | |
335 | - error = swap_write_page(handle, data_of(*snapshot), | |
336 | - &bio); | |
337 | - if (error) | |
338 | - break; | |
339 | - if (!(nr_pages % m)) | |
340 | - printk("\b\b\b\b%3d%%", nr_pages / m); | |
341 | - nr_pages++; | |
342 | - } | |
343 | - } while (ret > 0); | |
333 | + if (ret <= 0) | |
334 | + break; | |
335 | + ret = swap_write_page(handle, data_of(*snapshot), &bio); | |
336 | + if (ret) | |
337 | + break; | |
338 | + if (!(nr_pages % m)) | |
339 | + printk("\b\b\b\b%3d%%", nr_pages / m); | |
340 | + nr_pages++; | |
341 | + } | |
344 | 342 | err2 = wait_on_bio_chain(&bio); |
345 | 343 | do_gettimeofday(&stop); |
346 | - if (!error) | |
347 | - error = err2; | |
348 | - if (!error) | |
344 | + if (!ret) | |
345 | + ret = err2; | |
346 | + if (!ret) | |
349 | 347 | printk("\b\b\b\bdone\n"); |
348 | + else | |
349 | + printk("\n"); | |
350 | 350 | swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); |
351 | - return error; | |
351 | + return ret; | |
352 | 352 | } |
353 | 353 | |
354 | 354 | /** |
... | ... | @@ -536,7 +536,8 @@ |
536 | 536 | snapshot_write_finalize(snapshot); |
537 | 537 | if (!snapshot_image_loaded(snapshot)) |
538 | 538 | error = -ENODATA; |
539 | - } | |
539 | + } else | |
540 | + printk("\n"); | |
540 | 541 | swsusp_show_speed(&start, &stop, nr_to_read, "Read"); |
541 | 542 | return error; |
542 | 543 | } |
... | ... | @@ -572,8 +573,6 @@ |
572 | 573 | error = load_image(&handle, &snapshot, header->pages - 1); |
573 | 574 | release_swap_reader(&handle); |
574 | 575 | |
575 | - blkdev_put(resume_bdev, FMODE_READ); | |
576 | - | |
577 | 576 | if (!error) |
578 | 577 | pr_debug("PM: Image successfully loaded\n"); |
579 | 578 | else |
... | ... | @@ -596,7 +595,7 @@ |
596 | 595 | error = bio_read_page(swsusp_resume_block, |
597 | 596 | swsusp_header, NULL); |
598 | 597 | if (error) |
599 | - return error; | |
598 | + goto put; | |
600 | 599 | |
601 | 600 | if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) { |
602 | 601 | memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10); |
603 | 602 | |
... | ... | @@ -604,8 +603,10 @@ |
604 | 603 | error = bio_write_page(swsusp_resume_block, |
605 | 604 | swsusp_header, NULL); |
606 | 605 | } else { |
607 | - return -EINVAL; | |
606 | + error = -EINVAL; | |
608 | 607 | } |
608 | + | |
609 | +put: | |
609 | 610 | if (error) |
610 | 611 | blkdev_put(resume_bdev, FMODE_READ); |
611 | 612 | else |