static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); int ret; /* * Systems with the TI redriver that loses port status change events * need to have the registers polled during D3, so avoid D3cold. */ if (xhci->quirks & XHCI_COMP_MODE_QUIRK) pci_d3cold_disable(pdev); if (xhci->quirks & XHCI_PME_STUCK_QUIRK) xhci_pme_quirk(hcd); if (xhci->quirks & XHCI_SSIC_PORT_UNUSED) xhci_ssic_port_unused_quirk(hcd, true); ret = xhci_suspend(xhci, do_wakeup); if (ret && (xhci->quirks & XHCI_SSIC_PORT_UNUSED)) xhci_ssic_port_unused_quirk(hcd, false); return ret; }
static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); return xhci_suspend(xhci, true); }
static int xhci_plat_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); return xhci_suspend(xhci); }
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); int retval = 0; if (hcd->state != HC_STATE_SUSPENDED || xhci->shared_hcd->state != HC_STATE_SUSPENDED) return -EINVAL; retval = xhci_suspend(xhci); return retval; }
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); /* * Systems with the TI redriver that loses port status change events * need to have the registers polled during D3, so avoid D3cold. */ if (xhci_compliance_mode_recovery_timer_quirk_check()) pdev->no_d3cold = true; return xhci_suspend(xhci); }
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); /* * Systems with the TI redriver that loses port status change events * need to have the registers polled during D3, so avoid D3cold. */ if (xhci->quirks & XHCI_COMP_MODE_QUIRK) pdev->no_d3cold = true; return xhci_suspend(xhci); }
static int ubi32_xhci_drv_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); int retval = 0; if (hcd->state != HC_STATE_SUSPENDED || xhci->shared_hcd->state != HC_STATE_SUSPENDED) return -EINVAL; retval = xhci_suspend(xhci); return retval; }
static int __maybe_unused xhci_histb_suspend(struct device *dev) { struct xhci_hcd_histb *histb = dev_get_drvdata(dev); struct usb_hcd *hcd = histb->hcd; struct xhci_hcd *xhci = hcd_to_xhci(hcd); int ret; ret = xhci_suspend(xhci, device_may_wakeup(dev)); if (!device_may_wakeup(dev)) xhci_histb_host_disable(histb); return ret; }
static int exynos_xhci_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct exynos_xhci_hcd *exynos_xhci; struct usb_hcd *hcd; struct xhci_hcd *xhci; int retval = 0; #ifdef CONFIG_PM_RUNTIME dev_dbg(dev, "%s: usage_count = %d\n", __func__, atomic_read(&dev->power.usage_count)); #endif exynos_xhci = dev_get_drvdata(dev); if (!exynos_xhci) return -EINVAL; hcd = exynos_xhci->hcd; if (!hcd) return -EINVAL; /* Prevent any more root-hub status calls from the timer * The HCD might still restart the timer (if a port status change * interrupt occurs), but usb_hcd_poll_rh_status() won't invoke * the hub_status_data() callback. */ hcd->rh_pollable = 0; hcd->shared_hcd->rh_pollable = 0; xhci = hcd_to_xhci(hcd); if (hcd->state != HC_STATE_SUSPENDED || xhci->shared_hcd->state != HC_STATE_SUSPENDED) dev_err(dev, "%s: HC state is not suspended!\n", __func__); #ifdef CONFIG_USB_SUSPEND if (pm_runtime_suspended(dev)) { dev_dbg(dev, "xhci is runtime suspended\n"); return 0; } #endif retval = xhci_suspend(xhci, 0); if (retval < 0) dev_err(dev, "%s: cannot stop xHC\n", __func__); pm_runtime_put_sync(dev->parent); exynos_drd_put(pdev); return retval; }
static int xhci_plat_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); /* * xhci_suspend() needs `do_wakeup` to know whether host is allowed * to do wakeup during suspend. Since xhci_plat_suspend is currently * only designed for system suspend, device_may_wakeup() is enough * to dertermine whether host is allowed to do wakeup. Need to * reconsider this when xhci_plat_suspend enlarges its scope, e.g., * also applies to runtime suspend. */ return xhci_suspend(xhci, device_may_wakeup(dev)); }
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); int retval = 0; if (hcd->state != HC_STATE_SUSPENDED || xhci->shared_hcd->state != HC_STATE_SUSPENDED) return -EINVAL; if (xhci->quirks & XHCI_PME_STUCK_QUIRK) xhci_pme_quirk(xhci); retval = xhci_suspend(xhci, do_wakeup); return retval; }
static int exynos_xhci_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct exynos_xhci_hcd *exynos_xhci; struct usb_hcd *hcd; struct xhci_hcd *xhci; int retval = 0; #ifdef CONFIG_PM_RUNTIME dev_dbg(dev, "%s: usage_count = %d\n", __func__, atomic_read(&dev->power.usage_count)); #endif exynos_xhci = dev_get_drvdata(dev); if (!exynos_xhci) return -EINVAL; hcd = exynos_xhci->hcd; if (!hcd) return -EINVAL; xhci = hcd_to_xhci(hcd); if (hcd->state != HC_STATE_SUSPENDED || xhci->shared_hcd->state != HC_STATE_SUSPENDED) dev_err(dev, "%s: HC state is not suspended!\n", __func__); #ifdef CONFIG_USB_SUSPEND if (pm_runtime_suspended(dev)) { dev_dbg(dev, "xhci is runtime suspended\n"); return 0; } #endif retval = xhci_suspend(xhci); if (retval < 0) dev_err(dev, "%s: cannot stop xHC\n", __func__); pm_runtime_put_sync(dev->parent); exynos_drd_put(pdev); return retval; }
static int exynos_xhci_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct exynos_xhci_hcd *exynos_xhci; struct usb_hcd *hcd; struct xhci_hcd *xhci; int retval = 0; dev_dbg(dev, "%s\n", __func__); exynos_xhci = dev_get_drvdata(dev); if (!exynos_xhci) return -EINVAL; hcd = exynos_xhci->hcd; if (!hcd) return -EINVAL; xhci = hcd_to_xhci(hcd); if (hcd->state != HC_STATE_SUSPENDED || xhci->shared_hcd->state != HC_STATE_SUSPENDED) { dev_dbg(dev, "%s: HC state is not suspended!\n", __func__); return -EAGAIN; } retval = xhci_suspend(xhci, 0); if (retval < 0) dev_err(dev, "%s: cannot stop xHC\n", __func__); pm_runtime_put_sync(exynos_xhci->dev->parent); exynos_drd_put(pdev); return retval; }
/* dwc_hcd_suspend_common and dwc_hcd_resume_common are refer to * suspend_common and resume_common in usb core. * Because the usb core function just support PCI device. * So re-write them in here to support platform devices. */ static int dwc_hcd_suspend_common(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct usb_hcd *hcd = platform_get_drvdata(pdev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); int retval = 0; u32 data = 0; if (!xhci) { dev_dbg(dev, "%s: host already stop!\n", __func__); return 0; } /* Root hub suspend should have stopped all downstream traffic, * and all bus master traffic. And done so for both the interface * and the stub usb_device (which we check here). But maybe it * didn't; writing sysfs power/state files ignores such rules... */ if (HCD_RH_RUNNING(hcd)) { dev_warn(dev, "Root hub is not suspended\n"); return -EBUSY; } if (hcd->shared_hcd) { hcd = hcd->shared_hcd; if (HCD_RH_RUNNING(hcd)) { dev_warn(dev, "Secondary root hub is not suspended\n"); return -EBUSY; } } if (!HCD_DEAD(hcd)) { /* Optimization: Don't suspend if a root-hub wakeup is * pending and it would cause the HCD to wake up anyway. */ if (HCD_WAKEUP_PENDING(hcd)) return -EBUSY; if (hcd->shared_hcd && HCD_WAKEUP_PENDING(hcd->shared_hcd)) return -EBUSY; if (hcd->state != HC_STATE_SUSPENDED || xhci->shared_hcd->state != HC_STATE_SUSPENDED) retval = -EINVAL; if (!retval) { /* The auto-resume is diabled by default. Need enable it * if there have valid connection. To ensure that when * device resumes, host does resume reflect within * 900 usec as in USB spec. */ if (if_usb_devices_connected(xhci) == 1) dwc_xhci_enable_phy_auto_resume( xhci->main_hcd, true); /* Ensure that suspend enable are set for * USB2 and USB3 PHY */ dwc_xhci_enable_phy_suspend(hcd, true); data = readl(hcd->regs + GCTL); data |= GCTL_GBL_HIBERNATION_EN; writel(data, hcd->regs + GCTL); dev_dbg(hcd->self.controller, "set xhci hibernation enable!\n"); retval = xhci_suspend(xhci); } /* Check again in case wakeup raced with pci_suspend */ if ((retval == 0 && HCD_WAKEUP_PENDING(hcd)) || (retval == 0 && hcd->shared_hcd && HCD_WAKEUP_PENDING(hcd->shared_hcd))) { xhci_resume(xhci, false); retval = -EBUSY; } if (retval) return retval; } synchronize_irq(dwc3_xhci.otg_irqnum); return retval; }
static int xhci_pci_suspend(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); return xhci_suspend(xhci); }