aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/main.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/base/power/main.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/base/power/main.c')
-rw-r--r--drivers/base/power/main.c333
1 files changed, 297 insertions, 36 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 8aa2443182d5..941fcb87e52a 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -23,8 +23,9 @@
23#include <linux/pm.h> 23#include <linux/pm.h>
24#include <linux/pm_runtime.h> 24#include <linux/pm_runtime.h>
25#include <linux/resume-trace.h> 25#include <linux/resume-trace.h>
26#include <linux/rwsem.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/sched.h>
28#include <linux/async.h>
28 29
29#include "../base.h" 30#include "../base.h"
30#include "power.h" 31#include "power.h"
@@ -34,14 +35,15 @@
34 * because children are guaranteed to be discovered after parents, and 35 * because children are guaranteed to be discovered after parents, and
35 * are inserted at the back of the list on discovery. 36 * are inserted at the back of the list on discovery.
36 * 37 *
37 * Since device_pm_add() may be called with a device semaphore held, 38 * Since device_pm_add() may be called with a device lock held,
38 * we must never try to acquire a device semaphore while holding 39 * we must never try to acquire a device lock while holding
39 * dpm_list_mutex. 40 * dpm_list_mutex.
40 */ 41 */
41 42
42LIST_HEAD(dpm_list); 43LIST_HEAD(dpm_list);
43 44
44static DEFINE_MUTEX(dpm_list_mtx); 45static DEFINE_MUTEX(dpm_list_mtx);
46static pm_message_t pm_transition;
45 47
46/* 48/*
47 * Set once the preparation of devices for a PM transition has started, reset 49 * Set once the preparation of devices for a PM transition has started, reset
@@ -56,6 +58,7 @@ static bool transition_started;
56void device_pm_init(struct device *dev) 58void device_pm_init(struct device *dev)
57{ 59{
58 dev->power.status = DPM_ON; 60 dev->power.status = DPM_ON;
61 init_completion(&dev->power.completion);
59 pm_runtime_init(dev); 62 pm_runtime_init(dev);
60} 63}
61 64
@@ -111,6 +114,7 @@ void device_pm_remove(struct device *dev)
111 pr_debug("PM: Removing info for %s:%s\n", 114 pr_debug("PM: Removing info for %s:%s\n",
112 dev->bus ? dev->bus->name : "No Bus", 115 dev->bus ? dev->bus->name : "No Bus",
113 kobject_name(&dev->kobj)); 116 kobject_name(&dev->kobj));
117 complete_all(&dev->power.completion);
114 mutex_lock(&dpm_list_mtx); 118 mutex_lock(&dpm_list_mtx);
115 list_del_init(&dev->power.entry); 119 list_del_init(&dev->power.entry);
116 mutex_unlock(&dpm_list_mtx); 120 mutex_unlock(&dpm_list_mtx);
@@ -161,6 +165,57 @@ void device_pm_move_last(struct device *dev)
161 list_move_tail(&dev->power.entry, &dpm_list); 165 list_move_tail(&dev->power.entry, &dpm_list);
162} 166}
163 167
168static ktime_t initcall_debug_start(struct device *dev)
169{
170 ktime_t calltime = ktime_set(0, 0);
171
172 if (initcall_debug) {
173 pr_info("calling %s+ @ %i\n",
174 dev_name(dev), task_pid_nr(current));
175 calltime = ktime_get();
176 }
177
178 return calltime;
179}
180
181static void initcall_debug_report(struct device *dev, ktime_t calltime,
182 int error)
183{
184 ktime_t delta, rettime;
185
186 if (initcall_debug) {
187 rettime = ktime_get();
188 delta = ktime_sub(rettime, calltime);
189 pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
190 error, (unsigned long long)ktime_to_ns(delta) >> 10);
191 }
192}
193
194/**
195 * dpm_wait - Wait for a PM operation to complete.
196 * @dev: Device to wait for.
197 * @async: If unset, wait only if the device's power.async_suspend flag is set.
198 */
199static void dpm_wait(struct device *dev, bool async)
200{
201 if (!dev)
202 return;
203
204 if (async || (pm_async_enabled && dev->power.async_suspend))
205 wait_for_completion(&dev->power.completion);
206}
207
208static int dpm_wait_fn(struct device *dev, void *async_ptr)
209{
210 dpm_wait(dev, *((bool *)async_ptr));
211 return 0;
212}
213
214static void dpm_wait_for_children(struct device *dev, bool async)
215{
216 device_for_each_child(dev, &async, dpm_wait_fn);
217}
218
164/** 219/**
165 * pm_op - Execute the PM operation appropriate for given PM event. 220 * pm_op - Execute the PM operation appropriate for given PM event.
166 * @dev: Device to handle. 221 * @dev: Device to handle.
@@ -172,6 +227,9 @@ static int pm_op(struct device *dev,
172 pm_message_t state) 227 pm_message_t state)
173{ 228{
174 int error = 0; 229 int error = 0;
230 ktime_t calltime;
231
232 calltime = initcall_debug_start(dev);
175 233
176 switch (state.event) { 234 switch (state.event) {
177#ifdef CONFIG_SUSPEND 235#ifdef CONFIG_SUSPEND
@@ -219,6 +277,9 @@ static int pm_op(struct device *dev,
219 default: 277 default:
220 error = -EINVAL; 278 error = -EINVAL;
221 } 279 }
280
281 initcall_debug_report(dev, calltime, error);
282
222 return error; 283 return error;
223} 284}
224 285
@@ -236,6 +297,14 @@ static int pm_noirq_op(struct device *dev,
236 pm_message_t state) 297 pm_message_t state)
237{ 298{
238 int error = 0; 299 int error = 0;
300 ktime_t calltime, delta, rettime;
301
302 if (initcall_debug) {
303 pr_info("calling %s+ @ %i, parent: %s\n",
304 dev_name(dev), task_pid_nr(current),
305 dev->parent ? dev_name(dev->parent) : "none");
306 calltime = ktime_get();
307 }
239 308
240 switch (state.event) { 309 switch (state.event) {
241#ifdef CONFIG_SUSPEND 310#ifdef CONFIG_SUSPEND
@@ -283,6 +352,15 @@ static int pm_noirq_op(struct device *dev,
283 default: 352 default:
284 error = -EINVAL; 353 error = -EINVAL;
285 } 354 }
355
356 if (initcall_debug) {
357 rettime = ktime_get();
358 delta = ktime_sub(rettime, calltime);
359 printk("initcall %s_i+ returned %d after %Ld usecs\n",
360 dev_name(dev), error,
361 (unsigned long long)ktime_to_ns(delta) >> 10);
362 }
363
286 return error; 364 return error;
287} 365}
288 366
@@ -324,6 +402,23 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info,
324 kobject_name(&dev->kobj), pm_verb(state.event), info, error); 402 kobject_name(&dev->kobj), pm_verb(state.event), info, error);
325} 403}
326 404
405static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info)
406{
407 ktime_t calltime;
408 s64 usecs64;
409 int usecs;
410
411 calltime = ktime_get();
412 usecs64 = ktime_to_ns(ktime_sub(calltime, starttime));
413 do_div(usecs64, NSEC_PER_USEC);
414 usecs = usecs64;
415 if (usecs == 0)
416 usecs = 1;
417 pr_info("PM: %s%s%s of devices complete after %ld.%03ld msecs\n",
418 info ?: "", info ? " " : "", pm_verb(state.event),
419 usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC);
420}
421
327/*------------------------- Resume routines -------------------------*/ 422/*------------------------- Resume routines -------------------------*/
328 423
329/** 424/**
@@ -341,14 +436,26 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
341 TRACE_DEVICE(dev); 436 TRACE_DEVICE(dev);
342 TRACE_RESUME(0); 437 TRACE_RESUME(0);
343 438
344 if (!dev->bus) 439 if (dev->bus && dev->bus->pm) {
345 goto End;
346
347 if (dev->bus->pm) {
348 pm_dev_dbg(dev, state, "EARLY "); 440 pm_dev_dbg(dev, state, "EARLY ");
349 error = pm_noirq_op(dev, dev->bus->pm, state); 441 error = pm_noirq_op(dev, dev->bus->pm, state);
442 if (error)
443 goto End;
350 } 444 }
351 End: 445
446 if (dev->type && dev->type->pm) {
447 pm_dev_dbg(dev, state, "EARLY type ");
448 error = pm_noirq_op(dev, dev->type->pm, state);
449 if (error)
450 goto End;
451 }
452
453 if (dev->class && dev->class->pm) {
454 pm_dev_dbg(dev, state, "EARLY class ");
455 error = pm_noirq_op(dev, dev->class->pm, state);
456 }
457
458End:
352 TRACE_RESUME(error); 459 TRACE_RESUME(error);
353 return error; 460 return error;
354} 461}
@@ -363,6 +470,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
363void dpm_resume_noirq(pm_message_t state) 470void dpm_resume_noirq(pm_message_t state)
364{ 471{
365 struct device *dev; 472 struct device *dev;
473 ktime_t starttime = ktime_get();
366 474
367 mutex_lock(&dpm_list_mtx); 475 mutex_lock(&dpm_list_mtx);
368 transition_started = false; 476 transition_started = false;
@@ -376,23 +484,48 @@ void dpm_resume_noirq(pm_message_t state)
376 pm_dev_err(dev, state, " early", error); 484 pm_dev_err(dev, state, " early", error);
377 } 485 }
378 mutex_unlock(&dpm_list_mtx); 486 mutex_unlock(&dpm_list_mtx);
487 dpm_show_time(starttime, state, "early");
379 resume_device_irqs(); 488 resume_device_irqs();
380} 489}
381EXPORT_SYMBOL_GPL(dpm_resume_noirq); 490EXPORT_SYMBOL_GPL(dpm_resume_noirq);
382 491
383/** 492/**
493 * legacy_resume - Execute a legacy (bus or class) resume callback for device.
494 * @dev: Device to resume.
495 * @cb: Resume callback to execute.
496 */
497static int legacy_resume(struct device *dev, int (*cb)(struct device *dev))
498{
499 int error;
500 ktime_t calltime;
501
502 calltime = initcall_debug_start(dev);
503
504 error = cb(dev);
505 suspend_report_result(cb, error);
506
507 initcall_debug_report(dev, calltime, error);
508
509 return error;
510}
511
512/**
384 * device_resume - Execute "resume" callbacks for given device. 513 * device_resume - Execute "resume" callbacks for given device.
385 * @dev: Device to handle. 514 * @dev: Device to handle.
386 * @state: PM transition of the system being carried out. 515 * @state: PM transition of the system being carried out.
516 * @async: If true, the device is being resumed asynchronously.
387 */ 517 */
388static int device_resume(struct device *dev, pm_message_t state) 518static int device_resume(struct device *dev, pm_message_t state, bool async)
389{ 519{
390 int error = 0; 520 int error = 0;
391 521
392 TRACE_DEVICE(dev); 522 TRACE_DEVICE(dev);
393 TRACE_RESUME(0); 523 TRACE_RESUME(0);
394 524
395 down(&dev->sem); 525 dpm_wait(dev->parent, async);
526 device_lock(dev);
527
528 dev->power.status = DPM_RESUMING;
396 529
397 if (dev->bus) { 530 if (dev->bus) {
398 if (dev->bus->pm) { 531 if (dev->bus->pm) {
@@ -400,7 +533,7 @@ static int device_resume(struct device *dev, pm_message_t state)
400 error = pm_op(dev, dev->bus->pm, state); 533 error = pm_op(dev, dev->bus->pm, state);
401 } else if (dev->bus->resume) { 534 } else if (dev->bus->resume) {
402 pm_dev_dbg(dev, state, "legacy "); 535 pm_dev_dbg(dev, state, "legacy ");
403 error = dev->bus->resume(dev); 536 error = legacy_resume(dev, dev->bus->resume);
404 } 537 }
405 if (error) 538 if (error)
406 goto End; 539 goto End;
@@ -421,16 +554,34 @@ static int device_resume(struct device *dev, pm_message_t state)
421 error = pm_op(dev, dev->class->pm, state); 554 error = pm_op(dev, dev->class->pm, state);
422 } else if (dev->class->resume) { 555 } else if (dev->class->resume) {
423 pm_dev_dbg(dev, state, "legacy class "); 556 pm_dev_dbg(dev, state, "legacy class ");
424 error = dev->class->resume(dev); 557 error = legacy_resume(dev, dev->class->resume);
425 } 558 }
426 } 559 }
427 End: 560 End:
428 up(&dev->sem); 561 device_unlock(dev);
562 complete_all(&dev->power.completion);
429 563
430 TRACE_RESUME(error); 564 TRACE_RESUME(error);
431 return error; 565 return error;
432} 566}
433 567
568static void async_resume(void *data, async_cookie_t cookie)
569{
570 struct device *dev = (struct device *)data;
571 int error;
572
573 error = device_resume(dev, pm_transition, true);
574 if (error)
575 pm_dev_err(dev, pm_transition, " async", error);
576 put_device(dev);
577}
578
579static bool is_async(struct device *dev)
580{
581 return dev->power.async_suspend && pm_async_enabled
582 && !pm_trace_is_enabled();
583}
584
434/** 585/**
435 * dpm_resume - Execute "resume" callbacks for non-sysdev devices. 586 * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
436 * @state: PM transition of the system being carried out. 587 * @state: PM transition of the system being carried out.
@@ -441,20 +592,33 @@ static int device_resume(struct device *dev, pm_message_t state)
441static void dpm_resume(pm_message_t state) 592static void dpm_resume(pm_message_t state)
442{ 593{
443 struct list_head list; 594 struct list_head list;
595 struct device *dev;
596 ktime_t starttime = ktime_get();
444 597
445 INIT_LIST_HEAD(&list); 598 INIT_LIST_HEAD(&list);
446 mutex_lock(&dpm_list_mtx); 599 mutex_lock(&dpm_list_mtx);
447 while (!list_empty(&dpm_list)) { 600 pm_transition = state;
448 struct device *dev = to_device(dpm_list.next); 601
602 list_for_each_entry(dev, &dpm_list, power.entry) {
603 if (dev->power.status < DPM_OFF)
604 continue;
605
606 INIT_COMPLETION(dev->power.completion);
607 if (is_async(dev)) {
608 get_device(dev);
609 async_schedule(async_resume, dev);
610 }
611 }
449 612
613 while (!list_empty(&dpm_list)) {
614 dev = to_device(dpm_list.next);
450 get_device(dev); 615 get_device(dev);
451 if (dev->power.status >= DPM_OFF) { 616 if (dev->power.status >= DPM_OFF && !is_async(dev)) {
452 int error; 617 int error;
453 618
454 dev->power.status = DPM_RESUMING;
455 mutex_unlock(&dpm_list_mtx); 619 mutex_unlock(&dpm_list_mtx);
456 620
457 error = device_resume(dev, state); 621 error = device_resume(dev, state, false);
458 622
459 mutex_lock(&dpm_list_mtx); 623 mutex_lock(&dpm_list_mtx);
460 if (error) 624 if (error)
@@ -469,6 +633,8 @@ static void dpm_resume(pm_message_t state)
469 } 633 }
470 list_splice(&list, &dpm_list); 634 list_splice(&list, &dpm_list);
471 mutex_unlock(&dpm_list_mtx); 635 mutex_unlock(&dpm_list_mtx);
636 async_synchronize_full();
637 dpm_show_time(starttime, state, NULL);
472} 638}
473 639
474/** 640/**
@@ -478,7 +644,7 @@ static void dpm_resume(pm_message_t state)
478 */ 644 */
479static void device_complete(struct device *dev, pm_message_t state) 645static void device_complete(struct device *dev, pm_message_t state)
480{ 646{
481 down(&dev->sem); 647 device_lock(dev);
482 648
483 if (dev->class && dev->class->pm && dev->class->pm->complete) { 649 if (dev->class && dev->class->pm && dev->class->pm->complete) {
484 pm_dev_dbg(dev, state, "completing class "); 650 pm_dev_dbg(dev, state, "completing class ");
@@ -495,7 +661,7 @@ static void device_complete(struct device *dev, pm_message_t state)
495 dev->bus->pm->complete(dev); 661 dev->bus->pm->complete(dev);
496 } 662 }
497 663
498 up(&dev->sem); 664 device_unlock(dev);
499} 665}
500 666
501/** 667/**
@@ -521,7 +687,7 @@ static void dpm_complete(pm_message_t state)
521 mutex_unlock(&dpm_list_mtx); 687 mutex_unlock(&dpm_list_mtx);
522 688
523 device_complete(dev, state); 689 device_complete(dev, state);
524 pm_runtime_put_noidle(dev); 690 pm_runtime_put_sync(dev);
525 691
526 mutex_lock(&dpm_list_mtx); 692 mutex_lock(&dpm_list_mtx);
527 } 693 }
@@ -584,13 +750,26 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
584{ 750{
585 int error = 0; 751 int error = 0;
586 752
587 if (!dev->bus) 753 if (dev->class && dev->class->pm) {
588 return 0; 754 pm_dev_dbg(dev, state, "LATE class ");
755 error = pm_noirq_op(dev, dev->class->pm, state);
756 if (error)
757 goto End;
758 }
589 759
590 if (dev->bus->pm) { 760 if (dev->type && dev->type->pm) {
761 pm_dev_dbg(dev, state, "LATE type ");
762 error = pm_noirq_op(dev, dev->type->pm, state);
763 if (error)
764 goto End;
765 }
766
767 if (dev->bus && dev->bus->pm) {
591 pm_dev_dbg(dev, state, "LATE "); 768 pm_dev_dbg(dev, state, "LATE ");
592 error = pm_noirq_op(dev, dev->bus->pm, state); 769 error = pm_noirq_op(dev, dev->bus->pm, state);
593 } 770 }
771
772End:
594 return error; 773 return error;
595} 774}
596 775
@@ -604,6 +783,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
604int dpm_suspend_noirq(pm_message_t state) 783int dpm_suspend_noirq(pm_message_t state)
605{ 784{
606 struct device *dev; 785 struct device *dev;
786 ktime_t starttime = ktime_get();
607 int error = 0; 787 int error = 0;
608 788
609 suspend_device_irqs(); 789 suspend_device_irqs();
@@ -619,20 +799,51 @@ int dpm_suspend_noirq(pm_message_t state)
619 mutex_unlock(&dpm_list_mtx); 799 mutex_unlock(&dpm_list_mtx);
620 if (error) 800 if (error)
621 dpm_resume_noirq(resume_event(state)); 801 dpm_resume_noirq(resume_event(state));
802 else
803 dpm_show_time(starttime, state, "late");
622 return error; 804 return error;
623} 805}
624EXPORT_SYMBOL_GPL(dpm_suspend_noirq); 806EXPORT_SYMBOL_GPL(dpm_suspend_noirq);
625 807
626/** 808/**
809 * legacy_suspend - Execute a legacy (bus or class) suspend callback for device.
810 * @dev: Device to suspend.
811 * @state: PM transition of the system being carried out.
812 * @cb: Suspend callback to execute.
813 */
814static int legacy_suspend(struct device *dev, pm_message_t state,
815 int (*cb)(struct device *dev, pm_message_t state))
816{
817 int error;
818 ktime_t calltime;
819
820 calltime = initcall_debug_start(dev);
821
822 error = cb(dev, state);
823 suspend_report_result(cb, error);
824
825 initcall_debug_report(dev, calltime, error);
826
827 return error;
828}
829
830static int async_error;
831
832/**
627 * device_suspend - Execute "suspend" callbacks for given device. 833 * device_suspend - Execute "suspend" callbacks for given device.
628 * @dev: Device to handle. 834 * @dev: Device to handle.
629 * @state: PM transition of the system being carried out. 835 * @state: PM transition of the system being carried out.
836 * @async: If true, the device is being suspended asynchronously.
630 */ 837 */
631static int device_suspend(struct device *dev, pm_message_t state) 838static int __device_suspend(struct device *dev, pm_message_t state, bool async)
632{ 839{
633 int error = 0; 840 int error = 0;
634 841
635 down(&dev->sem); 842 dpm_wait_for_children(dev, async);
843 device_lock(dev);
844
845 if (async_error)
846 goto End;
636 847
637 if (dev->class) { 848 if (dev->class) {
638 if (dev->class->pm) { 849 if (dev->class->pm) {
@@ -640,8 +851,7 @@ static int device_suspend(struct device *dev, pm_message_t state)
640 error = pm_op(dev, dev->class->pm, state); 851 error = pm_op(dev, dev->class->pm, state);
641 } else if (dev->class->suspend) { 852 } else if (dev->class->suspend) {
642 pm_dev_dbg(dev, state, "legacy class "); 853 pm_dev_dbg(dev, state, "legacy class ");
643 error = dev->class->suspend(dev, state); 854 error = legacy_suspend(dev, state, dev->class->suspend);
644 suspend_report_result(dev->class->suspend, error);
645 } 855 }
646 if (error) 856 if (error)
647 goto End; 857 goto End;
@@ -662,16 +872,47 @@ static int device_suspend(struct device *dev, pm_message_t state)
662 error = pm_op(dev, dev->bus->pm, state); 872 error = pm_op(dev, dev->bus->pm, state);
663 } else if (dev->bus->suspend) { 873 } else if (dev->bus->suspend) {
664 pm_dev_dbg(dev, state, "legacy "); 874 pm_dev_dbg(dev, state, "legacy ");
665 error = dev->bus->suspend(dev, state); 875 error = legacy_suspend(dev, state, dev->bus->suspend);
666 suspend_report_result(dev->bus->suspend, error);
667 } 876 }
668 } 877 }
878
879 if (!error)
880 dev->power.status = DPM_OFF;
881
669 End: 882 End:
670 up(&dev->sem); 883 device_unlock(dev);
884 complete_all(&dev->power.completion);
671 885
672 return error; 886 return error;
673} 887}
674 888
889static void async_suspend(void *data, async_cookie_t cookie)
890{
891 struct device *dev = (struct device *)data;
892 int error;
893
894 error = __device_suspend(dev, pm_transition, true);
895 if (error) {
896 pm_dev_err(dev, pm_transition, " async", error);
897 async_error = error;
898 }
899
900 put_device(dev);
901}
902
903static int device_suspend(struct device *dev)
904{
905 INIT_COMPLETION(dev->power.completion);
906
907 if (pm_async_enabled && dev->power.async_suspend) {
908 get_device(dev);
909 async_schedule(async_suspend, dev);
910 return 0;
911 }
912
913 return __device_suspend(dev, pm_transition, false);
914}
915
675/** 916/**
676 * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices. 917 * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
677 * @state: PM transition of the system being carried out. 918 * @state: PM transition of the system being carried out.
@@ -679,17 +920,20 @@ static int device_suspend(struct device *dev, pm_message_t state)
679static int dpm_suspend(pm_message_t state) 920static int dpm_suspend(pm_message_t state)
680{ 921{
681 struct list_head list; 922 struct list_head list;
923 ktime_t starttime = ktime_get();
682 int error = 0; 924 int error = 0;
683 925
684 INIT_LIST_HEAD(&list); 926 INIT_LIST_HEAD(&list);
685 mutex_lock(&dpm_list_mtx); 927 mutex_lock(&dpm_list_mtx);
928 pm_transition = state;
929 async_error = 0;
686 while (!list_empty(&dpm_list)) { 930 while (!list_empty(&dpm_list)) {
687 struct device *dev = to_device(dpm_list.prev); 931 struct device *dev = to_device(dpm_list.prev);
688 932
689 get_device(dev); 933 get_device(dev);
690 mutex_unlock(&dpm_list_mtx); 934 mutex_unlock(&dpm_list_mtx);
691 935
692 error = device_suspend(dev, state); 936 error = device_suspend(dev);
693 937
694 mutex_lock(&dpm_list_mtx); 938 mutex_lock(&dpm_list_mtx);
695 if (error) { 939 if (error) {
@@ -697,13 +941,19 @@ static int dpm_suspend(pm_message_t state)
697 put_device(dev); 941 put_device(dev);
698 break; 942 break;
699 } 943 }
700 dev->power.status = DPM_OFF;
701 if (!list_empty(&dev->power.entry)) 944 if (!list_empty(&dev->power.entry))
702 list_move(&dev->power.entry, &list); 945 list_move(&dev->power.entry, &list);
703 put_device(dev); 946 put_device(dev);
947 if (async_error)
948 break;
704 } 949 }
705 list_splice(&list, dpm_list.prev); 950 list_splice(&list, dpm_list.prev);
706 mutex_unlock(&dpm_list_mtx); 951 mutex_unlock(&dpm_list_mtx);
952 async_synchronize_full();
953 if (!error)
954 error = async_error;
955 if (!error)
956 dpm_show_time(starttime, state, NULL);
707 return error; 957 return error;
708} 958}
709 959
@@ -719,7 +969,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
719{ 969{
720 int error = 0; 970 int error = 0;
721 971
722 down(&dev->sem); 972 device_lock(dev);
723 973
724 if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) { 974 if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) {
725 pm_dev_dbg(dev, state, "preparing "); 975 pm_dev_dbg(dev, state, "preparing ");
@@ -743,7 +993,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
743 suspend_report_result(dev->class->pm->prepare, error); 993 suspend_report_result(dev->class->pm->prepare, error);
744 } 994 }
745 End: 995 End:
746 up(&dev->sem); 996 device_unlock(dev);
747 997
748 return error; 998 return error;
749} 999}
@@ -772,7 +1022,7 @@ static int dpm_prepare(pm_message_t state)
772 pm_runtime_get_noresume(dev); 1022 pm_runtime_get_noresume(dev);
773 if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) { 1023 if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) {
774 /* Wake-up requested during system sleep transition. */ 1024 /* Wake-up requested during system sleep transition. */
775 pm_runtime_put_noidle(dev); 1025 pm_runtime_put_sync(dev);
776 error = -EBUSY; 1026 error = -EBUSY;
777 } else { 1027 } else {
778 error = device_prepare(dev, state); 1028 error = device_prepare(dev, state);
@@ -827,3 +1077,14 @@ void __suspend_report_result(const char *function, void *fn, int ret)
827 printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret); 1077 printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
828} 1078}
829EXPORT_SYMBOL_GPL(__suspend_report_result); 1079EXPORT_SYMBOL_GPL(__suspend_report_result);
1080
1081/**
1082 * device_pm_wait_for_dev - Wait for suspend/resume of a device to complete.
1083 * @dev: Device to wait for.
1084 * @subordinate: Device that needs to wait for @dev.
1085 */
1086void device_pm_wait_for_dev(struct device *subordinate, struct device *dev)
1087{
1088 dpm_wait(dev, subordinate->power.async_suspend);
1089}
1090EXPORT_SYMBOL_GPL(device_pm_wait_for_dev);