diff mbox

PM / sleep: Don't unset parent's direct_complete

Message ID 1427297276-6370-1-git-send-email-tomeu.vizoso@collabora.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Tomeu Vizoso March 25, 2015, 3:27 p.m. UTC
If a device isn't going to be fully-suspended because there isn't an
implementation of the suspend callback, there's no need to make sure
that its parent is going to be fully-suspended as well.

Without this change, USB interface devices will always prevent the
proper USB device to stay in runtime suspension when the system
suspends.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
---

Hi,

I'm not sure if this is the right fix, because I don't see why the USB
interface devices are in the dpm_list in the first place, so any comments will
be welcome.

Thanks,

Tomeu

---
 drivers/base/power/main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Alan Stern March 25, 2015, 5:55 p.m. UTC | #1
On Wed, 25 Mar 2015, Tomeu Vizoso wrote:

> If a device isn't going to be fully-suspended because there isn't an
> implementation of the suspend callback, there's no need to make sure
> that its parent is going to be fully-suspended as well.

What do you mean by "fully-suspended"?

What if the parent has several children?  Maybe some of them have 
implementations of the suspend callback and the others don't.  Will 
your patch do the right thing then?

> Without this change, USB interface devices will always prevent the
> proper USB device to stay in runtime suspension when the system
> suspends.

For USB it doesn't matter; everything gets resumed when the system 
wakes up.

> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
> ---
> 
> Hi,
> 
> I'm not sure if this is the right fix,

What are you trying to fix?  Is something currently wrong?

>  because I don't see why the USB
> interface devices are in the dpm_list in the first place, so any comments will
> be welcome.

_Every_ device is in the dpm_list, including USB interfaces.

If your goal is to prevent USB devices from being resumed when the
system wakes up, then the correct approach is to make usb_dev_prepare()  
return 1 rather than 0 under the appropriate conditions, and to add a
dev_pm_ops to the usb_if_device_type structure with a prepare callback 
that returns 1.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Stern March 25, 2015, 6:05 p.m. UTC | #2
On Wed, 25 Mar 2015, Alan Stern wrote:

> On Wed, 25 Mar 2015, Tomeu Vizoso wrote:
> 
> > If a device isn't going to be fully-suspended because there isn't an
> > implementation of the suspend callback, there's no need to make sure
> > that its parent is going to be fully-suspended as well.
> 
> What do you mean by "fully-suspended"?
> 
> What if the parent has several children?  Maybe some of them have 
> implementations of the suspend callback and the others don't.  Will 
> your patch do the right thing then?

After thinking about it some more, I realized this won't be a problem.

But what if the device has a child that _does_ have a suspend callback?  
In that case the child will need to be resumed, so the device's parent
cannot be allowed to remain in runtime suspend when the system wakes
up.  Hence the parent's direct_complete must be cleared.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 3d874ec..6bac53f 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1438,7 +1438,9 @@  static int __device_suspend(struct device *dev, pm_message_t state, bool async)
 		if (parent) {
 			spin_lock_irq(&parent->power.lock);
 
-			dev->parent->power.direct_complete = false;
+			if (callback)
+				parent->power.direct_complete = false;
+
 			if (dev->power.wakeup_path
 			    && !dev->parent->power.ignore_children)
 				dev->parent->power.wakeup_path = true;