On Fri, 7 Nov 2014, Sebastian Andrzej Siewior wrote: > > Ah. In usb_resume(), what happened after usb_resume_both() returned? > > The code says this: > > > > status = usb_resume_both(udev, msg); > > if (status == 0) { > > pm_runtime_disable(dev); > > pm_runtime_set_active(dev); > > pm_runtime_enable(dev); > > unbind_marked_interfaces(udev); > > } > > > > So if usb_resume_both() returns 0, the runtime PM status is supposed to > > get changed to RPM_ACTIVE by the pm_runtime_set_active() call. > > so it returns 0 but pm_runtime_set_active() return with -EBUSY: > __pm_runtime_set_status() { > … > if (parent) { > if (… && parent->power.runtime_status != RPM_ACTIVE) { > error = -EBUSY; > … > if (error) > goto out; > … > > The parent is musb-hdrc.1.auto. The sort order of resume is: > > musb-dsps 47401c00.usb: bus resume > => dsps_resume() (glue layer) > musb-hdrc musb-hdrc.1.auto: bus resume > => musb_resume(2328) > and after musb_resume() completes I see usb_resume() being invoked (and > the first hub resume). > Later, once khubd kicks in, I see musb_runtime_resume() probably via > usb_autopm_get_interface(hub). > > That means the musb-hcd is not RPM_ACTIVE after resume and this is what > USB expects. Exactly. > If I put pm_runtime_get_sync() + put in musb_resume() then the problem > is gone. I don't see ehci-hcd doing this in resume, in fact I don't see > ehci doing pm_runtime_* at all. So for ehci the device is probably > always RPM_ACTIVE. No, it doesn't always have to be RPM_ACTIVE. Remember, the most common implementation of EHCI is the PCI version. In drivers/pci/pci-driver.c, the pci_pm_suspend() routine calls pm_runtime_resume(). Therefore a PCI EHCI controller is always in the RPM_ACTIVE state _during a system sleep transition_. Maybe that's what you meant. EHCI controllers on other bus types might not behave so well. That probably should be fixed in ehci_resume(). > And musb does it only in probe and nowhere else. I would expect it in > the ISR as well but it is what it is. > On the the other hand: musb_resume() invokes usb_hcd_resume_root_hub() > what probably brings usb_resume() for the hub into the game. Shouldn't > it pm_get_sync() the HCD? No, usb_hcd_resume_root_hub() uses a freezable work queue. If it gets called during system resume, nothing will happen until after the resume is finished and the work queue starts running again. > And still, if the HCD has a short suspend > delay it might go into suspend before the khubd is invoked (but then it > probably kills the status URB). We need the musb device to go to the RPM_ACTIVE state at some point during the system suspend/resume, and to remain that way until after the root hub has been resumed. Putting the pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); calls in musb_resume() is one way to accomplish this. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html