Message ID | 201106182242.27814.rjw@sisk.pl (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
On Sat, 18 Jun 2011, Rafael J. Wysocki wrote: > > Okay; I should have been more careful. Thanks for fixing this up. > > No problem. :-) > > Appended is what I'm going to push to Linus. > > Thanks, > Rafael > > --- > From: Alan Stern <stern@rowland.harvard.edu> > Subject: PM: Fix async resume following suspend failure This looks fine. It's a little hard to test; you have to create an artificial suspend failure. Have you tried doing that? Alan Stern
On Sunday, June 19, 2011, Alan Stern wrote: > On Sat, 18 Jun 2011, Rafael J. Wysocki wrote: > > > > Okay; I should have been more careful. Thanks for fixing this up. > > > > No problem. :-) > > > > Appended is what I'm going to push to Linus. > > > > Thanks, > > Rafael > > > > --- > > From: Alan Stern <stern@rowland.harvard.edu> > > Subject: PM: Fix async resume following suspend failure > > This looks fine. It's a little hard to test; you have to create an > artificial suspend failure. Have you tried doing that? Not yet, but I have a plan to do that. :-) Thanks, Rafael
On Sunday, June 19, 2011, Rafael J. Wysocki wrote: > On Sunday, June 19, 2011, Alan Stern wrote: > > On Sat, 18 Jun 2011, Rafael J. Wysocki wrote: > > > > > > Okay; I should have been more careful. Thanks for fixing this up. > > > > > > No problem. :-) > > > > > > Appended is what I'm going to push to Linus. > > > > > > Thanks, > > > Rafael > > > > > > --- > > > From: Alan Stern <stern@rowland.harvard.edu> > > > Subject: PM: Fix async resume following suspend failure > > > > This looks fine. It's a little hard to test; you have to create an > > artificial suspend failure. Have you tried doing that? > > Not yet, but I have a plan to do that. :-) It appears to work. I've tested it using a fake battery module whose .suspend() always returns error code. Thanks, Rafael
Index: linux-2.6/include/linux/pm.h =================================================================== --- linux-2.6.orig/include/linux/pm.h +++ linux-2.6/include/linux/pm.h @@ -426,6 +426,7 @@ struct dev_pm_info { unsigned int can_wakeup:1; unsigned int async_suspend:1; bool is_prepared:1; /* Owned by the PM core */ + bool is_suspended:1; /* Ditto */ spinlock_t lock; #ifdef CONFIG_PM_SLEEP struct list_head entry; Index: linux-2.6/drivers/base/power/main.c =================================================================== --- linux-2.6.orig/drivers/base/power/main.c +++ linux-2.6/drivers/base/power/main.c @@ -58,6 +58,7 @@ static int async_error; void device_pm_init(struct device *dev) { dev->power.is_prepared = false; + dev->power.is_suspended = false; init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; @@ -517,6 +518,9 @@ static int device_resume(struct device * */ dev->power.is_prepared = false; + if (!dev->power.is_suspended) + goto Unlock; + if (dev->pwr_domain) { pm_dev_dbg(dev, state, "power domain "); error = pm_op(dev, &dev->pwr_domain->ops, state); @@ -552,6 +556,9 @@ static int device_resume(struct device * } End: + dev->power.is_suspended = false; + + Unlock: device_unlock(dev); complete_all(&dev->power.completion); @@ -839,11 +846,11 @@ static int __device_suspend(struct devic device_lock(dev); if (async_error) - goto End; + goto Unlock; if (pm_wakeup_pending()) { async_error = -EBUSY; - goto End; + goto Unlock; } if (dev->pwr_domain) { @@ -881,6 +888,9 @@ static int __device_suspend(struct devic } End: + dev->power.is_suspended = !error; + + Unlock: device_unlock(dev); complete_all(&dev->power.completion);