* dwc3_core_soft_reset - Issues core soft reset and PHY reset
  * @dwc: pointer to our context structure
  */
-static void dwc3_core_soft_reset(struct dwc3 *dwc)
+static int dwc3_core_soft_reset(struct dwc3 *dwc)
 {
        u32             reg;
+       int             ret;
 
        /* Before Resetting PHY, put Core in Reset */
        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
 
        usb_phy_init(dwc->usb2_phy);
        usb_phy_init(dwc->usb3_phy);
+       ret = phy_init(dwc->usb2_generic_phy);
+       if (ret < 0)
+               return ret;
+
+       ret = phy_init(dwc->usb3_generic_phy);
+       if (ret < 0) {
+               phy_exit(dwc->usb2_generic_phy);
+               return ret;
+       }
        mdelay(100);
 
        /* Clear USB3 PHY reset */
        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
        reg &= ~DWC3_GCTL_CORESOFTRESET;
        dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+
+       return 0;
 }
 
 /**
                cpu_relax();
        } while (true);
 
-       dwc3_core_soft_reset(dwc);
+       ret = dwc3_core_soft_reset(dwc);
+       if (ret)
+               goto err0;
 
        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
        reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
 err1:
        usb_phy_shutdown(dwc->usb2_phy);
        usb_phy_shutdown(dwc->usb3_phy);
+       phy_exit(dwc->usb2_generic_phy);
+       phy_exit(dwc->usb3_generic_phy);
 
 err0:
        return ret;
        dwc3_free_scratch_buffers(dwc);
        usb_phy_shutdown(dwc->usb2_phy);
        usb_phy_shutdown(dwc->usb3_phy);
+       phy_exit(dwc->usb2_generic_phy);
+       phy_exit(dwc->usb3_generic_phy);
 }
 
 #define DWC3_ALIGN_MASK                (16 - 1)
                }
        }
 
+       dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
+       if (IS_ERR(dwc->usb2_generic_phy)) {
+               ret = PTR_ERR(dwc->usb2_generic_phy);
+               if (ret == -ENOSYS || ret == -ENODEV) {
+                       dwc->usb2_generic_phy = NULL;
+               } else if (ret == -EPROBE_DEFER) {
+                       return ret;
+               } else {
+                       dev_err(dev, "no usb2 phy configured\n");
+                       return ret;
+               }
+       }
+
+       dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
+       if (IS_ERR(dwc->usb3_generic_phy)) {
+               ret = PTR_ERR(dwc->usb3_generic_phy);
+               if (ret == -ENOSYS || ret == -ENODEV) {
+                       dwc->usb3_generic_phy = NULL;
+               } else if (ret == -EPROBE_DEFER) {
+                       return ret;
+               } else {
+                       dev_err(dev, "no usb3 phy configured\n");
+                       return ret;
+               }
+       }
+
        dwc->xhci_resources[0].start = res->start;
        dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
                                        DWC3_XHCI_REGS_END;
 
        usb_phy_set_suspend(dwc->usb2_phy, 0);
        usb_phy_set_suspend(dwc->usb3_phy, 0);
+       ret = phy_power_on(dwc->usb2_generic_phy);
+       if (ret < 0)
+               goto err1;
+
+       ret = phy_power_on(dwc->usb3_generic_phy);
+       if (ret < 0)
+               goto err_usb2phy_power;
 
        ret = dwc3_event_buffers_setup(dwc);
        if (ret) {
                dev_err(dwc->dev, "failed to setup event buffers\n");
-               goto err1;
+               goto err_usb3phy_power;
        }
 
        switch (dwc->dr_mode) {
 err2:
        dwc3_event_buffers_cleanup(dwc);
 
+err_usb3phy_power:
+       phy_power_off(dwc->usb3_generic_phy);
+
+err_usb2phy_power:
+       phy_power_off(dwc->usb2_generic_phy);
+
 err1:
        usb_phy_set_suspend(dwc->usb2_phy, 1);
        usb_phy_set_suspend(dwc->usb3_phy, 1);
 
        usb_phy_set_suspend(dwc->usb2_phy, 1);
        usb_phy_set_suspend(dwc->usb3_phy, 1);
+       phy_power_off(dwc->usb2_generic_phy);
+       phy_power_off(dwc->usb3_generic_phy);
 
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
        usb_phy_shutdown(dwc->usb3_phy);
        usb_phy_shutdown(dwc->usb2_phy);
+       phy_exit(dwc->usb2_generic_phy);
+       phy_exit(dwc->usb3_generic_phy);
 
        return 0;
 }
 {
        struct dwc3     *dwc = dev_get_drvdata(dev);
        unsigned long   flags;
+       int             ret;
 
        usb_phy_init(dwc->usb3_phy);
        usb_phy_init(dwc->usb2_phy);
+       ret = phy_init(dwc->usb2_generic_phy);
+       if (ret < 0)
+               return ret;
+
+       ret = phy_init(dwc->usb3_generic_phy);
+       if (ret < 0)
+               goto err_usb2phy_init;
 
        spin_lock_irqsave(&dwc->lock, flags);
 
        pm_runtime_enable(dev);
 
        return 0;
+
+err_usb2phy_init:
+       phy_exit(dwc->usb2_generic_phy);
+
+       return ret;
 }
 
 static const struct dev_pm_ops dwc3_dev_pm_ops = {
 
 #include <linux/usb/gadget.h>
 #include <linux/usb/otg.h>
 
+#include <linux/phy/phy.h>
+
 /* Global constants */
 #define DWC3_EP0_BOUNCE_SIZE   512
 #define DWC3_ENDPOINTS_NUM     32
  * @dr_mode: requested mode of operation
  * @usb2_phy: pointer to USB2 PHY
  * @usb3_phy: pointer to USB3 PHY
+ * @usb2_generic_phy: pointer to USB2 PHY
+ * @usb3_generic_phy: pointer to USB3 PHY
  * @dcfg: saved contents of DCFG register
  * @gctl: saved contents of GCTL register
  * @isoch_delay: wValue from Set Isochronous Delay request;
        struct usb_phy          *usb2_phy;
        struct usb_phy          *usb3_phy;
 
+       struct phy              *usb2_generic_phy;
+       struct phy              *usb3_generic_phy;
+
        void __iomem            *regs;
        size_t                  regs_size;