aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/main.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-09-24 07:31:38 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-09-24 07:31:38 -0400
commit057d51a1268fe4be039db8ff0791fcfcb63a4f1b (patch)
tree50b7395aa526c5be9f3ae75836b5ad364db04877 /drivers/base/power/main.c
parent071f58279f274f749c4109aef86d899766014139 (diff)
parent88d26136a256576e444db312179e17af6dd0ea87 (diff)
Merge branch 'pm-sleep'
* pm-sleep: PM: Prevent runtime suspend during system resume PM / Sleep: use resume event when call dpm_resume_early Conflicts: drivers/base/power/main.c (trivial)
Diffstat (limited to 'drivers/base/power/main.c')
-rw-r--r--drivers/base/power/main.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 57f5814c2732..008e6786ae79 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -570,7 +570,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
570 pm_callback_t callback = NULL; 570 pm_callback_t callback = NULL;
571 char *info = NULL; 571 char *info = NULL;
572 int error = 0; 572 int error = 0;
573 bool put = false;
574 573
575 TRACE_DEVICE(dev); 574 TRACE_DEVICE(dev);
576 TRACE_RESUME(0); 575 TRACE_RESUME(0);
@@ -591,7 +590,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
591 goto Unlock; 590 goto Unlock;
592 591
593 pm_runtime_enable(dev); 592 pm_runtime_enable(dev);
594 put = true;
595 593
596 if (dev->pm_domain) { 594 if (dev->pm_domain) {
597 info = "power domain "; 595 info = "power domain ";
@@ -646,9 +644,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
646 644
647 TRACE_RESUME(error); 645 TRACE_RESUME(error);
648 646
649 if (put)
650 pm_runtime_put_sync(dev);
651
652 return error; 647 return error;
653} 648}
654 649
@@ -762,6 +757,8 @@ static void device_complete(struct device *dev, pm_message_t state)
762 } 757 }
763 758
764 device_unlock(dev); 759 device_unlock(dev);
760
761 pm_runtime_put_sync(dev);
765} 762}
766 763
767/** 764/**
@@ -1015,7 +1012,7 @@ int dpm_suspend_end(pm_message_t state)
1015 1012
1016 error = dpm_suspend_noirq(state); 1013 error = dpm_suspend_noirq(state);
1017 if (error) { 1014 if (error) {
1018 dpm_resume_early(state); 1015 dpm_resume_early(resume_event(state));
1019 return error; 1016 return error;
1020 } 1017 }
1021 1018
@@ -1062,12 +1059,16 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1062 if (async_error) 1059 if (async_error)
1063 goto Complete; 1060 goto Complete;
1064 1061
1065 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 */
1066 if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) 1068 if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
1067 pm_wakeup_event(dev, 0); 1069 pm_wakeup_event(dev, 0);
1068 1070
1069 if (pm_wakeup_pending()) { 1071 if (pm_wakeup_pending()) {
1070 pm_runtime_put_sync(dev);
1071 async_error = -EBUSY; 1072 async_error = -EBUSY;
1072 goto Complete; 1073 goto Complete;
1073 } 1074 }
@@ -1133,12 +1134,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1133 Complete: 1134 Complete:
1134 complete_all(&dev->power.completion); 1135 complete_all(&dev->power.completion);
1135 1136
1136 if (error) { 1137 if (error)
1137 pm_runtime_put_sync(dev);
1138 async_error = error; 1138 async_error = error;
1139 } else if (dev->power.is_suspended) { 1139 else if (dev->power.is_suspended)
1140 __pm_runtime_disable(dev, false); 1140 __pm_runtime_disable(dev, false);
1141 }
1142 1141
1143 return error; 1142 return error;
1144} 1143}
@@ -1234,6 +1233,14 @@ static int device_prepare(struct device *dev, pm_message_t state)
1234 if (dev->power.syscore) 1233 if (dev->power.syscore)
1235 return 0; 1234 return 0;
1236 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
1237 device_lock(dev); 1244 device_lock(dev);
1238 1245
1239 dev->power.wakeup_path = device_may_wakeup(dev); 1246 dev->power.wakeup_path = device_may_wakeup(dev);