On Fri, Feb 21, 2014 at 10:45 AM, Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx> wrote: >>> @@ -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. Right, but I assume you'd want to hold the reference until after the hub is registered, otherwise there's still a chance we suspend right before register. So I'm saying hold the reference until the registration process takes its own. -- 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