summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/dwc3/core.c46
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)