@@ -4753,6 +4753,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
* companion controller.
*/
hcd->has_tt = 1;
+ /* prevent USB2 runtime pm until USB3 parts are initialized */
+ pm_runtime_get_noresume(hcd->self.controller);
} else {
/* xHCI private pointer was set in xhci_pci_probe for the second
* registered roothub.
@@ -4765,6 +4767,9 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
if (xhci->hci_version < 0x100)
hcd->self.no_sg_constraint = 1;
+ /* USB3 initialized far enough to allow runtime pm suspend */
+ pm_runtime_put_noidle(hcd->self.controller);
+
Why the noresume and noidle versions? Shouldn't these be the _sync versions?
As I understood it the _sync versions may actually run pm_runtime_resume
/ pm_runtime_idle. Which is not what I'm looking for here.
Noresume and noidle will just increase / decrease the usage count and
that way prevent usb2 roothub register from calling xhci_suspend.
This is how I gather it works:
Round 1: add usb2 hcd
usb_add_hcd() // primary usb2 hcd
hcd->self.root_hub = usb_alloc_dev()
hcd->driver->reset(hcd) -> xhci_gen_setup()
if(primary_hcd) // true
pm_runtime_get_noresume(hcd->self.controller) // +1 usage
register_root_hub(hcd) -> usb_new_device(usb_dev)
pm_runtime_set_active(&udev->dev);
pm_runtime_get_noresume(&udev->dev);
pm_runtime_use_autosuspend(&udev->dev);
pm_runtime_enable(&udev->dev);
...
pm_runtime_put_sync_autosuspend(&udev->dev); this would trigger
xhci_suspend if all usages were 0. (for both roothub and controller)
which oopses as usb3 stuff is not yet initialized
Round 2: add usb 3 hcd
usb_add_hcd() // secondary usb3 hcd
hcd->self.root_hub = usb_alloc_dev()
hcd->driver->reset(hcd) -> xhci_gen_setup()
if(primary_hcd) // false
..
else
pm_runtime_put_noidle(hcd->self.controller) // -1 usage, *
register_root_hub(hcd) -> usb_new_device(usb_dev)
pm_runtime_set_active(&udev->dev);
pm_runtime_get_noresume(&udev->dev);
pm_runtime_use_autosuspend(&udev->dev);
pm_runtime_enable(&udev->dev);
...
pm_runtime_put_sync_autosuspend(&udev->dev); // ok to trigger would
trigger xhci_suspend if all usages were 0.
*) unnecessary to trigger any suspend as we're just about to register
the usb3 roothub. but we need to decrement the usage counter.
-Mathias
--
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