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.c66
1 files changed, 49 insertions, 17 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index b0b072a88f5f..a3c1404c7933 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -57,20 +57,17 @@ static pm_message_t pm_transition;
57static int async_error; 57static int async_error;
58 58
59/** 59/**
60 * device_pm_init - Initialize the PM-related part of a device object. 60 * device_pm_sleep_init - Initialize system suspend-related device fields.
61 * @dev: Device object being initialized. 61 * @dev: Device object being initialized.
62 */ 62 */
63void device_pm_init(struct device *dev) 63void device_pm_sleep_init(struct device *dev)
64{ 64{
65 dev->power.is_prepared = false; 65 dev->power.is_prepared = false;
66 dev->power.is_suspended = false; 66 dev->power.is_suspended = false;
67 init_completion(&dev->power.completion); 67 init_completion(&dev->power.completion);
68 complete_all(&dev->power.completion); 68 complete_all(&dev->power.completion);
69 dev->power.wakeup = NULL; 69 dev->power.wakeup = NULL;
70 spin_lock_init(&dev->power.lock);
71 pm_runtime_init(dev);
72 INIT_LIST_HEAD(&dev->power.entry); 70 INIT_LIST_HEAD(&dev->power.entry);
73 dev->power.power_state = PMSG_INVALID;
74} 71}
75 72
76/** 73/**
@@ -408,6 +405,9 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
408 TRACE_DEVICE(dev); 405 TRACE_DEVICE(dev);
409 TRACE_RESUME(0); 406 TRACE_RESUME(0);
410 407
408 if (dev->power.syscore)
409 goto Out;
410
411 if (dev->pm_domain) { 411 if (dev->pm_domain) {
412 info = "noirq power domain "; 412 info = "noirq power domain ";
413 callback = pm_noirq_op(&dev->pm_domain->ops, state); 413 callback = pm_noirq_op(&dev->pm_domain->ops, state);
@@ -429,6 +429,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
429 429
430 error = dpm_run_callback(callback, dev, state, info); 430 error = dpm_run_callback(callback, dev, state, info);
431 431
432 Out:
432 TRACE_RESUME(error); 433 TRACE_RESUME(error);
433 return error; 434 return error;
434} 435}
@@ -486,6 +487,9 @@ static int device_resume_early(struct device *dev, pm_message_t state)
486 TRACE_DEVICE(dev); 487 TRACE_DEVICE(dev);
487 TRACE_RESUME(0); 488 TRACE_RESUME(0);
488 489
490 if (dev->power.syscore)
491 goto Out;
492
489 if (dev->pm_domain) { 493 if (dev->pm_domain) {
490 info = "early power domain "; 494 info = "early power domain ";
491 callback = pm_late_early_op(&dev->pm_domain->ops, state); 495 callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -507,6 +511,7 @@ static int device_resume_early(struct device *dev, pm_message_t state)
507 511
508 error = dpm_run_callback(callback, dev, state, info); 512 error = dpm_run_callback(callback, dev, state, info);
509 513
514 Out:
510 TRACE_RESUME(error); 515 TRACE_RESUME(error);
511 return error; 516 return error;
512} 517}
@@ -565,11 +570,13 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
565 pm_callback_t callback = NULL; 570 pm_callback_t callback = NULL;
566 char *info = NULL; 571 char *info = NULL;
567 int error = 0; 572 int error = 0;
568 bool put = false;
569 573
570 TRACE_DEVICE(dev); 574 TRACE_DEVICE(dev);
571 TRACE_RESUME(0); 575 TRACE_RESUME(0);
572 576
577 if (dev->power.syscore)
578 goto Complete;
579
573 dpm_wait(dev->parent, async); 580 dpm_wait(dev->parent, async);
574 device_lock(dev); 581 device_lock(dev);
575 582
@@ -583,7 +590,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
583 goto Unlock; 590 goto Unlock;
584 591
585 pm_runtime_enable(dev); 592 pm_runtime_enable(dev);
586 put = true;
587 593
588 if (dev->pm_domain) { 594 if (dev->pm_domain) {
589 info = "power domain "; 595 info = "power domain ";
@@ -632,13 +638,12 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
632 638
633 Unlock: 639 Unlock:
634 device_unlock(dev); 640 device_unlock(dev);
641
642 Complete:
635 complete_all(&dev->power.completion); 643 complete_all(&dev->power.completion);
636 644
637 TRACE_RESUME(error); 645 TRACE_RESUME(error);
638 646
639 if (put)
640 pm_runtime_put_sync(dev);
641
642 return error; 647 return error;
643} 648}
644 649
@@ -722,6 +727,9 @@ static void device_complete(struct device *dev, pm_message_t state)
722 void (*callback)(struct device *) = NULL; 727 void (*callback)(struct device *) = NULL;
723 char *info = NULL; 728 char *info = NULL;
724 729
730 if (dev->power.syscore)
731 return;
732
725 device_lock(dev); 733 device_lock(dev);
726 734
727 if (dev->pm_domain) { 735 if (dev->pm_domain) {
@@ -749,6 +757,8 @@ static void device_complete(struct device *dev, pm_message_t state)
749 } 757 }
750 758
751 device_unlock(dev); 759 device_unlock(dev);
760
761 pm_runtime_put_sync(dev);
752} 762}
753 763
754/** 764/**
@@ -834,6 +844,9 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
834 pm_callback_t callback = NULL; 844 pm_callback_t callback = NULL;
835 char *info = NULL; 845 char *info = NULL;
836 846
847 if (dev->power.syscore)
848 return 0;
849
837 if (dev->pm_domain) { 850 if (dev->pm_domain) {
838 info = "noirq power domain "; 851 info = "noirq power domain ";
839 callback = pm_noirq_op(&dev->pm_domain->ops, state); 852 callback = pm_noirq_op(&dev->pm_domain->ops, state);
@@ -917,6 +930,9 @@ static int device_suspend_late(struct device *dev, pm_message_t state)
917 pm_callback_t callback = NULL; 930 pm_callback_t callback = NULL;
918 char *info = NULL; 931 char *info = NULL;
919 932
933 if (dev->power.syscore)
934 return 0;
935
920 if (dev->pm_domain) { 936 if (dev->pm_domain) {
921 info = "late power domain "; 937 info = "late power domain ";
922 callback = pm_late_early_op(&dev->pm_domain->ops, state); 938 callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -996,7 +1012,7 @@ int dpm_suspend_end(pm_message_t state)
996 1012
997 error = dpm_suspend_noirq(state); 1013 error = dpm_suspend_noirq(state);
998 if (error) { 1014 if (error) {
999 dpm_resume_early(state); 1015 dpm_resume_early(resume_event(state));
1000 return error; 1016 return error;
1001 } 1017 }
1002 1018
@@ -1043,16 +1059,23 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1043 if (async_error) 1059 if (async_error)
1044 goto Complete; 1060 goto Complete;
1045 1061
1046 pm_runtime_get_noresume(dev); 1062 /*
1063 * If a device configured to wake up the system from sleep states
1064 * has been suspended at run time and there's a resume request pending
1065 * for it, this is equivalent to the device signaling wakeup, so the
1066 * system suspend operation should be aborted.
1067 */
1047 if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) 1068 if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
1048 pm_wakeup_event(dev, 0); 1069 pm_wakeup_event(dev, 0);
1049 1070
1050 if (pm_wakeup_pending()) { 1071 if (pm_wakeup_pending()) {
1051 pm_runtime_put_sync(dev);
1052 async_error = -EBUSY; 1072 async_error = -EBUSY;
1053 goto Complete; 1073 goto Complete;
1054 } 1074 }
1055 1075
1076 if (dev->power.syscore)
1077 goto Complete;
1078
1056 device_lock(dev); 1079 device_lock(dev);
1057 1080
1058 if (dev->pm_domain) { 1081 if (dev->pm_domain) {
@@ -1111,12 +1134,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1111 Complete: 1134 Complete:
1112 complete_all(&dev->power.completion); 1135 complete_all(&dev->power.completion);
1113 1136
1114 if (error) { 1137 if (error)
1115 pm_runtime_put_sync(dev);
1116 async_error = error; 1138 async_error = error;
1117 } else if (dev->power.is_suspended) { 1139 else if (dev->power.is_suspended)
1118 __pm_runtime_disable(dev, false); 1140 __pm_runtime_disable(dev, false);
1119 }
1120 1141
1121 return error; 1142 return error;
1122} 1143}
@@ -1209,6 +1230,17 @@ static int device_prepare(struct device *dev, pm_message_t state)
1209 char *info = NULL; 1230 char *info = NULL;
1210 int error = 0; 1231 int error = 0;
1211 1232
1233 if (dev->power.syscore)
1234 return 0;
1235
1236 /*
1237 * If a device's parent goes into runtime suspend at the wrong time,
1238 * it won't be possible to resume the device. To prevent this we
1239 * block runtime suspend here, during the prepare phase, and allow
1240 * it again during the complete phase.
1241 */
1242 pm_runtime_get_noresume(dev);
1243
1212 device_lock(dev); 1244 device_lock(dev);
1213 1245
1214 dev->power.wakeup_path = device_may_wakeup(dev); 1246 dev->power.wakeup_path = device_may_wakeup(dev);