On Friday, September 03, 2010, Colin Cross wrote: > During suspend, the power.completion is expected to be set when a > device has not yet started suspending. Set it on init to fix a > corner case where a device is resumed when its parent has never > suspended. > > Consider three drivers, A, B, and C. The parent of A is C, and C > has async_suspend set. On boot, C->power.completion is initialized > to 0. > > During the first suspend: > suspend_devices_and_enter(...) > dpm_resume(...) > device_suspend(A) > device_suspend(B) returns error, aborts suspend > dpm_resume_end(...) > dpm_resume(...) > device_resume(A) > dpm_wait(A->parent == C) > wait_for_completion(C->power.completion) > > The wait_for_completion will never complete, because > complete_all(C->power.completion) will only be called from > device_suspend(C) or device_resume(C), neither of which is called > if suspend is aborted before C. > > After a successful suspend->resume cycle, where B doesn't abort > suspend, C->power.completion is left in the completed state by the > call to device_resume(C), and the same call path will work if B > aborts suspend. > > Signed-off-by: Colin Cross <ccross@xxxxxxxxxxx> Thanks, rebased on top of the current Linus' tree and applied to suspend-2.6/pm-fixes . Rafael > --- > drivers/base/power/main.c | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c > index cb784a0..b1b4029 100644 > --- a/drivers/base/power/main.c > +++ b/drivers/base/power/main.c > @@ -63,6 +63,7 @@ void device_pm_init(struct device *dev) > { > dev->power.status = DPM_ON; > init_completion(&dev->power.completion); > + complete_all(&dev->power.completion); > pm_runtime_init(dev); > } > > _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm