Message ID | 20191119081656.8746-1-henryl@nvidia.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v3] usb: xhci: only set D3hot for pci device | expand |
On 19.11.2019 10.16, Henry Lin wrote: > Xhci driver cannot call pci_set_power_state() on non-pci xhci host > controllers. For example, NVIDIA Tegra XHCI host controller which acts > as platform device with XHCI_SPURIOUS_WAKEUP quirk set in some platform > hits this issue during shutdown. > > Signed-off-by: Henry Lin <henryl@nvidia.com> Thanks, looks great. I like this solution. Keeps original code sequence, removes pci specific calls from generic xhci code, and at the same time it fixes the NVIDIA Tegra xHC shutdown issue. Adding to queue -Mathias
On Tue, Nov 19, 2019 at 04:16:56PM +0800, Henry Lin wrote: > diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c > index 6c17e3fe181a..e59346488f64 100644 > --- a/drivers/usb/host/xhci.c > +++ b/drivers/usb/host/xhci.c > @@ -770,7 +770,7 @@ static void xhci_stop(struct usb_hcd *hcd) > * > * This will only ever be called with the main usb_hcd (the USB3 roothub). > */ > -static void xhci_shutdown(struct usb_hcd *hcd) > +void xhci_shutdown(struct usb_hcd *hcd) > { > struct xhci_hcd *xhci = hcd_to_xhci(hcd); > > @@ -789,10 +789,6 @@ static void xhci_shutdown(struct usb_hcd *hcd) > xhci_dbg_trace(xhci, trace_xhci_dbg_init, > "xhci_shutdown completed - status = %x", > readl(&xhci->op_regs->status)); > - > - /* Yet another workaround for spurious wakeups at shutdown with HSW */ > - if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) > - pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot); > } Shouldn't this function also now need to be EXPORTed? Jack
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 1e0236e90687..1904ef56f61c 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -519,6 +519,18 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) } #endif /* CONFIG_PM */ +static void xhci_pci_shutdown(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + + xhci_shutdown(hcd); + + /* Yet another workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + pci_set_power_state(pdev, PCI_D3hot); +} + /*-------------------------------------------------------------------------*/ /* PCI driver selection metadata; PCI hotplugging uses this */ @@ -554,6 +566,7 @@ static int __init xhci_pci_init(void) #ifdef CONFIG_PM xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; xhci_pci_hc_driver.pci_resume = xhci_pci_resume; + xhci_pci_hc_driver.shutdown = xhci_pci_shutdown; #endif return pci_register_driver(&xhci_pci_driver); } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 6c17e3fe181a..e59346488f64 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -770,7 +770,7 @@ static void xhci_stop(struct usb_hcd *hcd) * * This will only ever be called with the main usb_hcd (the USB3 roothub). */ -static void xhci_shutdown(struct usb_hcd *hcd) +void xhci_shutdown(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); @@ -789,10 +789,6 @@ static void xhci_shutdown(struct usb_hcd *hcd) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xhci_shutdown completed - status = %x", readl(&xhci->op_regs->status)); - - /* Yet another workaround for spurious wakeups at shutdown with HSW */ - if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) - pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot); } #ifdef CONFIG_PM diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index f9f88626a57a..973d665052a2 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2050,6 +2050,7 @@ int xhci_start(struct xhci_hcd *xhci); int xhci_reset(struct xhci_hcd *xhci); int xhci_run(struct usb_hcd *hcd); int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); +void xhci_shutdown(struct usb_hcd *hcd); void xhci_init_driver(struct hc_driver *drv, const struct xhci_driver_overrides *over); int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
Xhci driver cannot call pci_set_power_state() on non-pci xhci host controllers. For example, NVIDIA Tegra XHCI host controller which acts as platform device with XHCI_SPURIOUS_WAKEUP quirk set in some platform hits this issue during shutdown. Signed-off-by: Henry Lin <henryl@nvidia.com> --- drivers/usb/host/xhci-pci.c | 13 +++++++++++++ drivers/usb/host/xhci.c | 6 +----- drivers/usb/host/xhci.h | 1 + 3 files changed, 15 insertions(+), 5 deletions(-)