aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/power/main.c')
-rw-r--r--drivers/base/power/main.c109
1 files changed, 72 insertions, 37 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index b5cef7e7de23..e2cc3d2e0ecc 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -383,10 +383,15 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
383 info = "EARLY class "; 383 info = "EARLY class ";
384 callback = pm_noirq_op(dev->class->pm, state); 384 callback = pm_noirq_op(dev->class->pm, state);
385 } else if (dev->bus && dev->bus->pm) { 385 } else if (dev->bus && dev->bus->pm) {
386 info = "EARLY "; 386 info = "EARLY bus ";
387 callback = pm_noirq_op(dev->bus->pm, state); 387 callback = pm_noirq_op(dev->bus->pm, state);
388 } 388 }
389 389
390 if (!callback && dev->driver && dev->driver->pm) {
391 info = "EARLY driver ";
392 callback = pm_noirq_op(dev->driver->pm, state);
393 }
394
390 error = dpm_run_callback(callback, dev, state, info); 395 error = dpm_run_callback(callback, dev, state, info);
391 396
392 TRACE_RESUME(error); 397 TRACE_RESUME(error);
@@ -464,20 +469,20 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
464 if (dev->pm_domain) { 469 if (dev->pm_domain) {
465 info = "power domain "; 470 info = "power domain ";
466 callback = pm_op(&dev->pm_domain->ops, state); 471 callback = pm_op(&dev->pm_domain->ops, state);
467 goto End; 472 goto Driver;
468 } 473 }
469 474
470 if (dev->type && dev->type->pm) { 475 if (dev->type && dev->type->pm) {
471 info = "type "; 476 info = "type ";
472 callback = pm_op(dev->type->pm, state); 477 callback = pm_op(dev->type->pm, state);
473 goto End; 478 goto Driver;
474 } 479 }
475 480
476 if (dev->class) { 481 if (dev->class) {
477 if (dev->class->pm) { 482 if (dev->class->pm) {
478 info = "class "; 483 info = "class ";
479 callback = pm_op(dev->class->pm, state); 484 callback = pm_op(dev->class->pm, state);
480 goto End; 485 goto Driver;
481 } else if (dev->class->resume) { 486 } else if (dev->class->resume) {
482 info = "legacy class "; 487 info = "legacy class ";
483 callback = dev->class->resume; 488 callback = dev->class->resume;
@@ -487,14 +492,21 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
487 492
488 if (dev->bus) { 493 if (dev->bus) {
489 if (dev->bus->pm) { 494 if (dev->bus->pm) {
490 info = ""; 495 info = "bus ";
491 callback = pm_op(dev->bus->pm, state); 496 callback = pm_op(dev->bus->pm, state);
492 } else if (dev->bus->resume) { 497 } else if (dev->bus->resume) {
493 info = "legacy "; 498 info = "legacy bus ";
494 callback = dev->bus->resume; 499 callback = dev->bus->resume;
500 goto End;
495 } 501 }
496 } 502 }
497 503
504 Driver:
505 if (!callback && dev->driver && dev->driver->pm) {
506 info = "driver ";
507 callback = pm_op(dev->driver->pm, state);
508 }
509
498 End: 510 End:
499 error = dpm_run_callback(callback, dev, state, info); 511 error = dpm_run_callback(callback, dev, state, info);
500 dev->power.is_suspended = false; 512 dev->power.is_suspended = false;
@@ -588,24 +600,33 @@ void dpm_resume(pm_message_t state)
588 */ 600 */
589static void device_complete(struct device *dev, pm_message_t state) 601static void device_complete(struct device *dev, pm_message_t state)
590{ 602{
603 void (*callback)(struct device *) = NULL;
604 char *info = NULL;
605
591 device_lock(dev); 606 device_lock(dev);
592 607
593 if (dev->pm_domain) { 608 if (dev->pm_domain) {
594 pm_dev_dbg(dev, state, "completing power domain "); 609 info = "completing power domain ";
595 if (dev->pm_domain->ops.complete) 610 callback = dev->pm_domain->ops.complete;
596 dev->pm_domain->ops.complete(dev);
597 } else if (dev->type && dev->type->pm) { 611 } else if (dev->type && dev->type->pm) {
598 pm_dev_dbg(dev, state, "completing type "); 612 info = "completing type ";
599 if (dev->type->pm->complete) 613 callback = dev->type->pm->complete;
600 dev->type->pm->complete(dev);
601 } else if (dev->class && dev->class->pm) { 614 } else if (dev->class && dev->class->pm) {
602 pm_dev_dbg(dev, state, "completing class "); 615 info = "completing class ";
603 if (dev->class->pm->complete) 616 callback = dev->class->pm->complete;
604 dev->class->pm->complete(dev);
605 } else if (dev->bus && dev->bus->pm) { 617 } else if (dev->bus && dev->bus->pm) {
606 pm_dev_dbg(dev, state, "completing "); 618 info = "completing bus ";
607 if (dev->bus->pm->complete) 619 callback = dev->bus->pm->complete;
608 dev->bus->pm->complete(dev); 620 }
621
622 if (!callback && dev->driver && dev->driver->pm) {
623 info = "completing driver ";
624 callback = dev->driver->pm->complete;
625 }
626
627 if (callback) {
628 pm_dev_dbg(dev, state, info);
629 callback(dev);
609 } 630 }
610 631
611 device_unlock(dev); 632 device_unlock(dev);
@@ -704,10 +725,15 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
704 info = "LATE class "; 725 info = "LATE class ";
705 callback = pm_noirq_op(dev->class->pm, state); 726 callback = pm_noirq_op(dev->class->pm, state);
706 } else if (dev->bus && dev->bus->pm) { 727 } else if (dev->bus && dev->bus->pm) {
707 info = "LATE "; 728 info = "LATE bus ";
708 callback = pm_noirq_op(dev->bus->pm, state); 729 callback = pm_noirq_op(dev->bus->pm, state);
709 } 730 }
710 731
732 if (!callback && dev->driver && dev->driver->pm) {
733 info = "LATE driver ";
734 callback = pm_noirq_op(dev->driver->pm, state);
735 }
736
711 return dpm_run_callback(callback, dev, state, info); 737 return dpm_run_callback(callback, dev, state, info);
712} 738}
713 739
@@ -832,16 +858,21 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
832 858
833 if (dev->bus) { 859 if (dev->bus) {
834 if (dev->bus->pm) { 860 if (dev->bus->pm) {
835 info = ""; 861 info = "bus ";
836 callback = pm_op(dev->bus->pm, state); 862 callback = pm_op(dev->bus->pm, state);
837 } else if (dev->bus->suspend) { 863 } else if (dev->bus->suspend) {
838 pm_dev_dbg(dev, state, "legacy "); 864 pm_dev_dbg(dev, state, "legacy bus ");
839 error = legacy_suspend(dev, state, dev->bus->suspend); 865 error = legacy_suspend(dev, state, dev->bus->suspend);
840 goto End; 866 goto End;
841 } 867 }
842 } 868 }
843 869
844 Run: 870 Run:
871 if (!callback && dev->driver && dev->driver->pm) {
872 info = "driver ";
873 callback = pm_op(dev->driver->pm, state);
874 }
875
845 error = dpm_run_callback(callback, dev, state, info); 876 error = dpm_run_callback(callback, dev, state, info);
846 877
847 End: 878 End:
@@ -949,6 +980,8 @@ int dpm_suspend(pm_message_t state)
949 */ 980 */
950static int device_prepare(struct device *dev, pm_message_t state) 981static int device_prepare(struct device *dev, pm_message_t state)
951{ 982{
983 int (*callback)(struct device *) = NULL;
984 char *info = NULL;
952 int error = 0; 985 int error = 0;
953 986
954 device_lock(dev); 987 device_lock(dev);
@@ -956,25 +989,27 @@ static int device_prepare(struct device *dev, pm_message_t state)
956 dev->power.wakeup_path = device_may_wakeup(dev); 989 dev->power.wakeup_path = device_may_wakeup(dev);
957 990
958 if (dev->pm_domain) { 991 if (dev->pm_domain) {
959 pm_dev_dbg(dev, state, "preparing power domain "); 992 info = "preparing power domain ";
960 if (dev->pm_domain->ops.prepare) 993 callback = dev->pm_domain->ops.prepare;
961 error = dev->pm_domain->ops.prepare(dev);
962 suspend_report_result(dev->pm_domain->ops.prepare, error);
963 } else if (dev->type && dev->type->pm) { 994 } else if (dev->type && dev->type->pm) {
964 pm_dev_dbg(dev, state, "preparing type "); 995 info = "preparing type ";
965 if (dev->type->pm->prepare) 996 callback = dev->type->pm->prepare;
966 error = dev->type->pm->prepare(dev);
967 suspend_report_result(dev->type->pm->prepare, error);
968 } else if (dev->class && dev->class->pm) { 997 } else if (dev->class && dev->class->pm) {
969 pm_dev_dbg(dev, state, "preparing class "); 998 info = "preparing class ";
970 if (dev->class->pm->prepare) 999 callback = dev->class->pm->prepare;
971 error = dev->class->pm->prepare(dev);
972 suspend_report_result(dev->class->pm->prepare, error);
973 } else if (dev->bus && dev->bus->pm) { 1000 } else if (dev->bus && dev->bus->pm) {
974 pm_dev_dbg(dev, state, "preparing "); 1001 info = "preparing bus ";
975 if (dev->bus->pm->prepare) 1002 callback = dev->bus->pm->prepare;
976 error = dev->bus->pm->prepare(dev); 1003 }
977 suspend_report_result(dev->bus->pm->prepare, error); 1004
1005 if (!callback && dev->driver && dev->driver->pm) {
1006 info = "preparing driver ";
1007 callback = dev->driver->pm->prepare;
1008 }
1009
1010 if (callback) {
1011 error = callback(dev);
1012 suspend_report_result(callback, error);
978 } 1013 }
979 1014
980 device_unlock(dev); 1015 device_unlock(dev);