Loading drivers/usb/core/driver.c +3 −2 Original line number Diff line number Diff line Loading @@ -1495,9 +1495,10 @@ int usb_resume(struct device *dev, pm_message_t msg) * Some buses would like to keep their devices in suspend * state after system resume. Their resume happen when * a remote wakeup is detected or interface driver start * I/O. * I/O. And in the case when the system is restoring from * hibernation, make sure all the devices are resumed. */ if (udev->bus->skip_resume) if (udev->bus->skip_resume && msg.event != PM_EVENT_RESTORE) return 0; /* For all calls, take the device back to full power and Loading drivers/usb/dwc3/core.c +19 −1 Original line number Diff line number Diff line Loading @@ -1567,6 +1567,19 @@ static int dwc3_suspend(struct device *dev) return 0; } static int dwc3_pm_restore(struct device *dev) { /* * Set the core as runtime active to prevent the runtime * PM ops being called before the PM restore is completed. */ pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); return 0; } static int dwc3_resume(struct device *dev) { struct dwc3 *dwc = dev_get_drvdata(dev); Loading @@ -1591,7 +1604,12 @@ static int dwc3_resume(struct device *dev) #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops dwc3_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) .suspend = dwc3_suspend, .resume = dwc3_resume, .freeze = dwc3_suspend, .thaw = dwc3_pm_restore, .poweroff = dwc3_suspend, .restore = dwc3_pm_restore, SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, dwc3_runtime_idle) }; Loading drivers/usb/dwc3/dwc3-msm.c +85 −15 Original line number Diff line number Diff line Loading @@ -2093,6 +2093,19 @@ static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc) dwc3_core_init(dwc); /* Re-configure event buffers */ dwc3_event_buffers_setup(dwc); /* Get initial P3 status and enable IN_P3 event */ val = dwc3_msm_read_reg_field(mdwc->base, DWC3_GDBGLTSSM, DWC3_GDBGLTSSM_LINKSTATE_MASK); atomic_set(&mdwc->in_p3, val == DWC3_LINK_STATE_U3); dwc3_msm_write_reg_field(mdwc->base, PWR_EVNT_IRQ_MASK_REG, PWR_EVNT_POWERDOWN_IN_P3_MASK, 1); if (mdwc->otg_state == OTG_STATE_A_HOST) { dev_dbg(mdwc->dev, "%s: set the core in host mode\n", __func__); dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); } } static int dwc3_msm_prepare_suspend(struct dwc3_msm *mdwc) Loading Loading @@ -2246,7 +2259,7 @@ static void configure_nonpdc_usb_interrupt(struct dwc3_msm *mdwc, } } static int dwc3_msm_suspend(struct dwc3_msm *mdwc) static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation) { int ret; struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); Loading Loading @@ -2363,8 +2376,8 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) clk_disable_unprepare(mdwc->xo_clk); /* Perform controller power collapse */ if (!mdwc->in_host_mode && (!mdwc->in_device_mode || mdwc->in_restart)) { if ((!mdwc->in_host_mode && (!mdwc->in_device_mode || mdwc->in_restart)) || hibernation) { mdwc->lpm_flags |= MDWC3_POWER_COLLAPSE; dev_dbg(mdwc->dev, "%s: power collapse\n", __func__); dwc3_msm_config_gdsc(mdwc, 0); Loading Loading @@ -2520,8 +2533,6 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) /* Recover from controller power collapse */ if (mdwc->lpm_flags & MDWC3_POWER_COLLAPSE) { u32 tmp; if (mdwc->iommu_map) { ret = arm_iommu_attach_device(mdwc->dev, mdwc->iommu_map); Loading @@ -2536,13 +2547,6 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) dwc3_msm_power_collapse_por(mdwc); /* Get initial P3 status and enable IN_P3 event */ tmp = dwc3_msm_read_reg_field(mdwc->base, DWC3_GDBGLTSSM, DWC3_GDBGLTSSM_LINKSTATE_MASK); atomic_set(&mdwc->in_p3, tmp == DWC3_LINK_STATE_U3); dwc3_msm_write_reg_field(mdwc->base, PWR_EVNT_IRQ_MASK_REG, PWR_EVNT_POWERDOWN_IN_P3_MASK, 1); mdwc->lpm_flags &= ~MDWC3_POWER_COLLAPSE; } Loading Loading @@ -4404,7 +4408,39 @@ static int dwc3_msm_pm_suspend(struct device *dev) return -EBUSY; } ret = dwc3_msm_suspend(mdwc); ret = dwc3_msm_suspend(mdwc, false); if (!ret) atomic_set(&mdwc->pm_suspended, 1); return ret; } static int dwc3_msm_pm_freeze(struct device *dev) { int ret = 0; struct dwc3_msm *mdwc = dev_get_drvdata(dev); struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); dev_dbg(dev, "dwc3-msm PM freeze\n"); dbg_event(0xFF, "PM Freeze", 0); flush_workqueue(mdwc->dwc3_wq); /* Resume the core to make sure we can power collapse it */ ret = dwc3_msm_resume(mdwc); /* * PHYs also needed to be power collapsed, so call the notify_disconnect * before suspend to ensure it. */ usb_phy_notify_disconnect(mdwc->hs_phy, USB_SPEED_HIGH); mdwc->hs_phy->flags &= ~PHY_HOST_MODE; if (mdwc->ss_phy) { usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER); mdwc->ss_phy->flags &= ~PHY_HOST_MODE; } ret = dwc3_msm_suspend(mdwc, true); if (!ret) atomic_set(&mdwc->pm_suspended, 1); Loading @@ -4426,6 +4462,35 @@ static int dwc3_msm_pm_resume(struct device *dev) /* kick in otg state machine */ queue_work(mdwc->dwc3_wq, &mdwc->resume_work); return 0; } static int dwc3_msm_pm_restore(struct device *dev) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); dev_dbg(dev, "dwc3-msm PM restore\n"); dbg_event(0xFF, "PM Restore", 0); atomic_set(&mdwc->pm_suspended, 0); dwc3_msm_resume(mdwc); pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); /* Restore PHY flags if hibernated in host mode */ if (mdwc->otg_state == OTG_STATE_A_HOST) { usb_phy_notify_connect(mdwc->hs_phy, USB_SPEED_HIGH); mdwc->hs_phy->flags |= PHY_HOST_MODE; if (mdwc->ss_phy) { usb_phy_notify_connect(mdwc->ss_phy, USB_SPEED_SUPER); mdwc->ss_phy->flags |= PHY_HOST_MODE; } } return 0; } #endif Loading @@ -4450,7 +4515,7 @@ static int dwc3_msm_runtime_suspend(struct device *dev) dev_dbg(dev, "DWC3-msm runtime suspend\n"); dbg_event(0xFF, "RT Sus", 0); return dwc3_msm_suspend(mdwc); return dwc3_msm_suspend(mdwc, false); } static int dwc3_msm_runtime_resume(struct device *dev) Loading @@ -4466,7 +4531,12 @@ static int dwc3_msm_runtime_resume(struct device *dev) #endif static const struct dev_pm_ops dwc3_msm_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dwc3_msm_pm_suspend, dwc3_msm_pm_resume) .suspend = dwc3_msm_pm_suspend, .resume = dwc3_msm_pm_resume, .freeze = dwc3_msm_pm_freeze, .restore = dwc3_msm_pm_restore, .thaw = dwc3_msm_pm_restore, .poweroff = dwc3_msm_pm_suspend, SET_RUNTIME_PM_OPS(dwc3_msm_runtime_suspend, dwc3_msm_runtime_resume, dwc3_msm_runtime_idle) }; Loading drivers/usb/host/xhci-plat.c +36 −1 Original line number Diff line number Diff line Loading @@ -439,6 +439,39 @@ static int xhci_plat_runtime_idle(struct device *dev) return -EBUSY; } static int xhci_plat_pm_freeze(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); if (!xhci) return 0; dev_dbg(dev, "xhci-plat freeze\n"); return xhci_suspend(xhci, false); } static int xhci_plat_pm_restore(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); int ret; if (!xhci) return 0; dev_dbg(dev, "xhci-plat restore\n"); ret = xhci_resume(xhci, true); pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); pm_runtime_mark_last_busy(dev); return ret; } static int xhci_plat_runtime_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); Loading Loading @@ -470,7 +503,9 @@ static int xhci_plat_runtime_resume(struct device *dev) } static const struct dev_pm_ops xhci_plat_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(NULL, NULL) .freeze = xhci_plat_pm_freeze, .restore = xhci_plat_pm_restore, .thaw = xhci_plat_pm_restore, SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, xhci_plat_runtime_resume, xhci_plat_runtime_idle) }; Loading drivers/usb/host/xhci.c +4 −2 Original line number Diff line number Diff line Loading @@ -947,7 +947,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) struct usb_hcd *hcd = xhci_to_hcd(xhci); u32 command; if (!hcd->state) if (!hcd->state || xhci->suspended) return 0; if (hcd->state != HC_STATE_SUSPENDED || Loading Loading @@ -1017,6 +1017,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) /* step 5: remove core well power */ /* synchronize irq when using MSI-X */ xhci_msix_sync_irqs(xhci); xhci->suspended = true; return rc; } Loading @@ -1036,7 +1037,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) int retval = 0; bool comp_timer_running = false; if (!hcd->state) if (!hcd->state || !xhci->suspended) return 0; /* Wait a bit if either of the roothubs need to settle from the Loading Loading @@ -1173,6 +1174,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) /* Re-enable port polling. */ xhci_dbg(xhci, "%s: starting port polling.\n", __func__); xhci->suspended = false; set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); usb_hcd_poll_rh_status(xhci->shared_hcd); set_bit(HCD_FLAG_POLL_RH, &hcd->flags); Loading Loading
drivers/usb/core/driver.c +3 −2 Original line number Diff line number Diff line Loading @@ -1495,9 +1495,10 @@ int usb_resume(struct device *dev, pm_message_t msg) * Some buses would like to keep their devices in suspend * state after system resume. Their resume happen when * a remote wakeup is detected or interface driver start * I/O. * I/O. And in the case when the system is restoring from * hibernation, make sure all the devices are resumed. */ if (udev->bus->skip_resume) if (udev->bus->skip_resume && msg.event != PM_EVENT_RESTORE) return 0; /* For all calls, take the device back to full power and Loading
drivers/usb/dwc3/core.c +19 −1 Original line number Diff line number Diff line Loading @@ -1567,6 +1567,19 @@ static int dwc3_suspend(struct device *dev) return 0; } static int dwc3_pm_restore(struct device *dev) { /* * Set the core as runtime active to prevent the runtime * PM ops being called before the PM restore is completed. */ pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); return 0; } static int dwc3_resume(struct device *dev) { struct dwc3 *dwc = dev_get_drvdata(dev); Loading @@ -1591,7 +1604,12 @@ static int dwc3_resume(struct device *dev) #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops dwc3_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) .suspend = dwc3_suspend, .resume = dwc3_resume, .freeze = dwc3_suspend, .thaw = dwc3_pm_restore, .poweroff = dwc3_suspend, .restore = dwc3_pm_restore, SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, dwc3_runtime_idle) }; Loading
drivers/usb/dwc3/dwc3-msm.c +85 −15 Original line number Diff line number Diff line Loading @@ -2093,6 +2093,19 @@ static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc) dwc3_core_init(dwc); /* Re-configure event buffers */ dwc3_event_buffers_setup(dwc); /* Get initial P3 status and enable IN_P3 event */ val = dwc3_msm_read_reg_field(mdwc->base, DWC3_GDBGLTSSM, DWC3_GDBGLTSSM_LINKSTATE_MASK); atomic_set(&mdwc->in_p3, val == DWC3_LINK_STATE_U3); dwc3_msm_write_reg_field(mdwc->base, PWR_EVNT_IRQ_MASK_REG, PWR_EVNT_POWERDOWN_IN_P3_MASK, 1); if (mdwc->otg_state == OTG_STATE_A_HOST) { dev_dbg(mdwc->dev, "%s: set the core in host mode\n", __func__); dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); } } static int dwc3_msm_prepare_suspend(struct dwc3_msm *mdwc) Loading Loading @@ -2246,7 +2259,7 @@ static void configure_nonpdc_usb_interrupt(struct dwc3_msm *mdwc, } } static int dwc3_msm_suspend(struct dwc3_msm *mdwc) static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation) { int ret; struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); Loading Loading @@ -2363,8 +2376,8 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) clk_disable_unprepare(mdwc->xo_clk); /* Perform controller power collapse */ if (!mdwc->in_host_mode && (!mdwc->in_device_mode || mdwc->in_restart)) { if ((!mdwc->in_host_mode && (!mdwc->in_device_mode || mdwc->in_restart)) || hibernation) { mdwc->lpm_flags |= MDWC3_POWER_COLLAPSE; dev_dbg(mdwc->dev, "%s: power collapse\n", __func__); dwc3_msm_config_gdsc(mdwc, 0); Loading Loading @@ -2520,8 +2533,6 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) /* Recover from controller power collapse */ if (mdwc->lpm_flags & MDWC3_POWER_COLLAPSE) { u32 tmp; if (mdwc->iommu_map) { ret = arm_iommu_attach_device(mdwc->dev, mdwc->iommu_map); Loading @@ -2536,13 +2547,6 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) dwc3_msm_power_collapse_por(mdwc); /* Get initial P3 status and enable IN_P3 event */ tmp = dwc3_msm_read_reg_field(mdwc->base, DWC3_GDBGLTSSM, DWC3_GDBGLTSSM_LINKSTATE_MASK); atomic_set(&mdwc->in_p3, tmp == DWC3_LINK_STATE_U3); dwc3_msm_write_reg_field(mdwc->base, PWR_EVNT_IRQ_MASK_REG, PWR_EVNT_POWERDOWN_IN_P3_MASK, 1); mdwc->lpm_flags &= ~MDWC3_POWER_COLLAPSE; } Loading Loading @@ -4404,7 +4408,39 @@ static int dwc3_msm_pm_suspend(struct device *dev) return -EBUSY; } ret = dwc3_msm_suspend(mdwc); ret = dwc3_msm_suspend(mdwc, false); if (!ret) atomic_set(&mdwc->pm_suspended, 1); return ret; } static int dwc3_msm_pm_freeze(struct device *dev) { int ret = 0; struct dwc3_msm *mdwc = dev_get_drvdata(dev); struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); dev_dbg(dev, "dwc3-msm PM freeze\n"); dbg_event(0xFF, "PM Freeze", 0); flush_workqueue(mdwc->dwc3_wq); /* Resume the core to make sure we can power collapse it */ ret = dwc3_msm_resume(mdwc); /* * PHYs also needed to be power collapsed, so call the notify_disconnect * before suspend to ensure it. */ usb_phy_notify_disconnect(mdwc->hs_phy, USB_SPEED_HIGH); mdwc->hs_phy->flags &= ~PHY_HOST_MODE; if (mdwc->ss_phy) { usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER); mdwc->ss_phy->flags &= ~PHY_HOST_MODE; } ret = dwc3_msm_suspend(mdwc, true); if (!ret) atomic_set(&mdwc->pm_suspended, 1); Loading @@ -4426,6 +4462,35 @@ static int dwc3_msm_pm_resume(struct device *dev) /* kick in otg state machine */ queue_work(mdwc->dwc3_wq, &mdwc->resume_work); return 0; } static int dwc3_msm_pm_restore(struct device *dev) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); dev_dbg(dev, "dwc3-msm PM restore\n"); dbg_event(0xFF, "PM Restore", 0); atomic_set(&mdwc->pm_suspended, 0); dwc3_msm_resume(mdwc); pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); /* Restore PHY flags if hibernated in host mode */ if (mdwc->otg_state == OTG_STATE_A_HOST) { usb_phy_notify_connect(mdwc->hs_phy, USB_SPEED_HIGH); mdwc->hs_phy->flags |= PHY_HOST_MODE; if (mdwc->ss_phy) { usb_phy_notify_connect(mdwc->ss_phy, USB_SPEED_SUPER); mdwc->ss_phy->flags |= PHY_HOST_MODE; } } return 0; } #endif Loading @@ -4450,7 +4515,7 @@ static int dwc3_msm_runtime_suspend(struct device *dev) dev_dbg(dev, "DWC3-msm runtime suspend\n"); dbg_event(0xFF, "RT Sus", 0); return dwc3_msm_suspend(mdwc); return dwc3_msm_suspend(mdwc, false); } static int dwc3_msm_runtime_resume(struct device *dev) Loading @@ -4466,7 +4531,12 @@ static int dwc3_msm_runtime_resume(struct device *dev) #endif static const struct dev_pm_ops dwc3_msm_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dwc3_msm_pm_suspend, dwc3_msm_pm_resume) .suspend = dwc3_msm_pm_suspend, .resume = dwc3_msm_pm_resume, .freeze = dwc3_msm_pm_freeze, .restore = dwc3_msm_pm_restore, .thaw = dwc3_msm_pm_restore, .poweroff = dwc3_msm_pm_suspend, SET_RUNTIME_PM_OPS(dwc3_msm_runtime_suspend, dwc3_msm_runtime_resume, dwc3_msm_runtime_idle) }; Loading
drivers/usb/host/xhci-plat.c +36 −1 Original line number Diff line number Diff line Loading @@ -439,6 +439,39 @@ static int xhci_plat_runtime_idle(struct device *dev) return -EBUSY; } static int xhci_plat_pm_freeze(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); if (!xhci) return 0; dev_dbg(dev, "xhci-plat freeze\n"); return xhci_suspend(xhci, false); } static int xhci_plat_pm_restore(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); int ret; if (!xhci) return 0; dev_dbg(dev, "xhci-plat restore\n"); ret = xhci_resume(xhci, true); pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); pm_runtime_mark_last_busy(dev); return ret; } static int xhci_plat_runtime_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); Loading Loading @@ -470,7 +503,9 @@ static int xhci_plat_runtime_resume(struct device *dev) } static const struct dev_pm_ops xhci_plat_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(NULL, NULL) .freeze = xhci_plat_pm_freeze, .restore = xhci_plat_pm_restore, .thaw = xhci_plat_pm_restore, SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, xhci_plat_runtime_resume, xhci_plat_runtime_idle) }; Loading
drivers/usb/host/xhci.c +4 −2 Original line number Diff line number Diff line Loading @@ -947,7 +947,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) struct usb_hcd *hcd = xhci_to_hcd(xhci); u32 command; if (!hcd->state) if (!hcd->state || xhci->suspended) return 0; if (hcd->state != HC_STATE_SUSPENDED || Loading Loading @@ -1017,6 +1017,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) /* step 5: remove core well power */ /* synchronize irq when using MSI-X */ xhci_msix_sync_irqs(xhci); xhci->suspended = true; return rc; } Loading @@ -1036,7 +1037,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) int retval = 0; bool comp_timer_running = false; if (!hcd->state) if (!hcd->state || !xhci->suspended) return 0; /* Wait a bit if either of the roothubs need to settle from the Loading Loading @@ -1173,6 +1174,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) /* Re-enable port polling. */ xhci_dbg(xhci, "%s: starting port polling.\n", __func__); xhci->suspended = false; set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); usb_hcd_poll_rh_status(xhci->shared_hcd); set_bit(HCD_FLAG_POLL_RH, &hcd->flags); Loading