diff options
-rw-r--r-- | drivers/usb/dwc3/core.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 717ff4e47f0..f397846c324 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -914,8 +914,52 @@ err_usb2phy_init: return ret; } +static int dwc3_restore(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + unsigned long flags; + int ret; + + ret = dwc3_core_soft_reset(dwc); + if (ret) + goto err; + + spin_lock_irqsave(&dwc->lock, flags); + + dwc3_event_buffers_setup(dwc); + dwc3_writel(dwc->regs, DWC3_GCTL, dwc->gctl); + + switch (dwc->dr_mode) { + case USB_DR_MODE_OTG: + dwc3_otg_resume(dwc); + case USB_DR_MODE_PERIPHERAL: + dwc3_gadget_resume(dwc); + /* FALLTHROUGH */ + case USB_DR_MODE_HOST: + default: + /* do nothing */ + break; + } + + spin_unlock_irqrestore(&dwc->lock, flags); + + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; + +err: + return ret; +} + 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_resume, + .poweroff = dwc3_suspend, + .restore = dwc3_restore, }; #define DWC3_PM_OPS &(dwc3_dev_pm_ops) |