Merge tag 'usb-for-v4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb...
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc2 / gadget.c
index ddd14a7257605bfcd6fad882229c4d509ff3321a..0abf73c91beb0f5eef5f25a4e46b7070ee03fdc2 100644 (file)
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/regulator/consumer.h>
 #include <linux/of_platform.h>
-#include <linux/phy/phy.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/phy.h>
-#include <linux/platform_data/s3c-hsotg.h>
 
 #include "core.h"
 #include "hw.h"
@@ -556,7 +552,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
        /* If endpoint is stalled, we will restart request later */
        ctrl = dwc2_readl(hsotg->regs + epctrl_reg);
 
-       if (ctrl & DXEPCTL_STALL) {
+       if (index && ctrl & DXEPCTL_STALL) {
                dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index);
                return;
        }
@@ -1206,9 +1202,10 @@ static void dwc2_hsotg_process_control(struct dwc2_hsotg *hsotg,
        int ret = 0;
        u32 dcfg;
 
-       dev_dbg(hsotg->dev, "ctrl Req=%02x, Type=%02x, V=%04x, L=%04x\n",
-                ctrl->bRequest, ctrl->bRequestType,
-                ctrl->wValue, ctrl->wLength);
+       dev_dbg(hsotg->dev,
+               "ctrl Type=%02x, Req=%02x, V=%04x, I=%04x, L=%04x\n",
+               ctrl->bRequestType, ctrl->bRequest, ctrl->wValue,
+               ctrl->wIndex, ctrl->wLength);
 
        if (ctrl->wLength == 0) {
                ep0->dir_in = 1;
@@ -1394,14 +1391,14 @@ static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg,
        if (hs_req->req.status == -EINPROGRESS)
                hs_req->req.status = result;
 
+       if (using_dma(hsotg))
+               dwc2_hsotg_unmap_dma(hsotg, hs_ep, hs_req);
+
        dwc2_hsotg_handle_unaligned_buf_complete(hsotg, hs_ep, hs_req);
 
        hs_ep->req = NULL;
        list_del_init(&hs_req->queue);
 
-       if (using_dma(hsotg))
-               dwc2_hsotg_unmap_dma(hsotg, hs_ep, hs_req);
-
        /*
         * call the complete request with the locks off, just in case the
         * request tries to queue more work for this endpoint.
@@ -1512,6 +1509,19 @@ static void dwc2_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in)
        dwc2_hsotg_program_zlp(hsotg, hsotg->eps_out[0]);
 }
 
+static void dwc2_hsotg_change_ep_iso_parity(struct dwc2_hsotg *hsotg,
+                       u32 epctl_reg)
+{
+       u32 ctrl;
+
+       ctrl = dwc2_readl(hsotg->regs + epctl_reg);
+       if (ctrl & DXEPCTL_EOFRNUM)
+               ctrl |= DXEPCTL_SETEVENFR;
+       else
+               ctrl |= DXEPCTL_SETODDFR;
+       dwc2_writel(ctrl, hsotg->regs + epctl_reg);
+}
+
 /**
  * dwc2_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO
  * @hsotg: The device instance
@@ -1582,6 +1592,16 @@ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
                return;
        }
 
+       /*
+        * Slave mode OUT transfers do not go through XferComplete so
+        * adjust the ISOC parity here.
+        */
+       if (!using_dma(hsotg)) {
+               hs_ep->has_correct_parity = 1;
+               if (hs_ep->isochronous && hs_ep->interval == 1)
+                       dwc2_hsotg_change_ep_iso_parity(hsotg, DOEPCTL(epnum));
+       }
+
        dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
 }
 
@@ -1954,13 +1974,9 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
                ints &= ~DXEPINT_XFERCOMPL;
 
        if (ints & DXEPINT_XFERCOMPL) {
-               if (hs_ep->isochronous && hs_ep->interval == 1) {
-                       if (ctrl & DXEPCTL_EOFRNUM)
-                               ctrl |= DXEPCTL_SETEVENFR;
-                       else
-                               ctrl |= DXEPCTL_SETODDFR;
-                       dwc2_writel(ctrl, hsotg->regs + epctl_reg);
-               }
+               hs_ep->has_correct_parity = 1;
+               if (hs_ep->isochronous && hs_ep->interval == 1)
+                       dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
 
                dev_dbg(hsotg->dev,
                        "%s: XferCompl: DxEPCTL=0x%08x, DXEPTSIZ=%08x\n",
@@ -2189,6 +2205,7 @@ void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg)
        }
 
        call_gadget(hsotg, disconnect);
+       hsotg->lx_state = DWC2_L3;
 }
 
 /**
@@ -2283,10 +2300,15 @@ static int dwc2_hsotg_corereset(struct dwc2_hsotg *hsotg)
 void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
                                                bool is_usb_reset)
 {
+       u32 intmsk;
        u32 val;
 
+       /* Kill any ep0 requests as controller will be reinitialized */
+       kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
+
        if (!is_usb_reset)
-               dwc2_hsotg_corereset(hsotg);
+               if (dwc2_hsotg_corereset(hsotg))
+                       return;
 
        /*
         * we must now enable ep0 ready for host detection and then
@@ -2310,14 +2332,17 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 
        /* Clear any pending interrupts */
        dwc2_writel(0xffffffff, hsotg->regs + GINTSTS);
-
-       dwc2_writel(GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT |
+       intmsk = GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT |
                GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF |
-               GINTSTS_CONIDSTSCHNG | GINTSTS_USBRST |
-               GINTSTS_RESETDET | GINTSTS_ENUMDONE |
-               GINTSTS_OTGINT | GINTSTS_USBSUSP |
-               GINTSTS_WKUPINT,
-               hsotg->regs + GINTMSK);
+               GINTSTS_USBRST | GINTSTS_RESETDET |
+               GINTSTS_ENUMDONE | GINTSTS_OTGINT |
+               GINTSTS_USBSUSP | GINTSTS_WKUPINT |
+               GINTSTS_INCOMPL_SOIN | GINTSTS_INCOMPL_SOOUT;
+
+       if (hsotg->core_params->external_id_pin_ctl <= 0)
+               intmsk |= GINTSTS_CONIDSTSCHNG;
+
+       dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 
        if (using_dma(hsotg))
                dwc2_writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN |
@@ -2414,7 +2439,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
        /* must be at-least 3ms to allow bus to see disconnect */
        mdelay(3);
 
-       hsotg->last_rst = jiffies;
+       hsotg->lx_state = DWC2_L0;
 }
 
 static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)
@@ -2451,6 +2476,36 @@ irq_retry:
 
        gintsts &= gintmsk;
 
+       if (gintsts & GINTSTS_RESETDET) {
+               dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__);
+
+               dwc2_writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS);
+
+               /* This event must be used only if controller is suspended */
+               if (hsotg->lx_state == DWC2_L2) {
+                       dwc2_exit_hibernation(hsotg, true);
+                       hsotg->lx_state = DWC2_L0;
+               }
+       }
+
+       if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) {
+
+               u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL);
+               u32 connected = hsotg->connected;
+
+               dev_dbg(hsotg->dev, "%s: USBRst\n", __func__);
+               dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n",
+                       dwc2_readl(hsotg->regs + GNPTXSTS));
+
+               dwc2_writel(GINTSTS_USBRST, hsotg->regs + GINTSTS);
+
+               /* Report disconnection if it is not already done. */
+               dwc2_hsotg_disconnect(hsotg);
+
+               if (usb_status & GOTGCTL_BSESVLD && connected)
+                       dwc2_hsotg_core_init_disconnected(hsotg, true);
+       }
+
        if (gintsts & GINTSTS_ENUMDONE) {
                dwc2_writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS);
 
@@ -2482,44 +2537,6 @@ irq_retry:
                }
        }
 
-       if (gintsts & GINTSTS_RESETDET) {
-               dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__);
-
-               dwc2_writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS);
-
-               /* This event must be used only if controller is suspended */
-               if (hsotg->lx_state == DWC2_L2) {
-                       dwc2_exit_hibernation(hsotg, true);
-                       hsotg->lx_state = DWC2_L0;
-               }
-       }
-
-       if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) {
-
-               u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL);
-
-               dev_dbg(hsotg->dev, "%s: USBRst\n", __func__);
-               dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n",
-                       dwc2_readl(hsotg->regs + GNPTXSTS));
-
-               dwc2_writel(GINTSTS_USBRST, hsotg->regs + GINTSTS);
-
-               /* Report disconnection if it is not already done. */
-               dwc2_hsotg_disconnect(hsotg);
-
-               if (usb_status & GOTGCTL_BSESVLD) {
-                       if (time_after(jiffies, hsotg->last_rst +
-                                      msecs_to_jiffies(200))) {
-
-                               kill_all_requests(hsotg, hsotg->eps_out[0],
-                                                         -ECONNRESET);
-
-                               hsotg->lx_state = DWC2_L0;
-                               dwc2_hsotg_core_init_disconnected(hsotg, true);
-                       }
-               }
-       }
-
        /* check both FIFOs */
 
        if (gintsts & GINTSTS_NPTXFEMP) {
@@ -2581,6 +2598,40 @@ irq_retry:
                dwc2_hsotg_dump(hsotg);
        }
 
+       if (gintsts & GINTSTS_INCOMPL_SOIN) {
+               u32 idx, epctl_reg;
+               struct dwc2_hsotg_ep *hs_ep;
+
+               dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOIN\n", __func__);
+               for (idx = 1; idx < hsotg->num_of_eps; idx++) {
+                       hs_ep = hsotg->eps_in[idx];
+
+                       if (!hs_ep->isochronous || hs_ep->has_correct_parity)
+                               continue;
+
+                       epctl_reg = DIEPCTL(idx);
+                       dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
+               }
+               dwc2_writel(GINTSTS_INCOMPL_SOIN, hsotg->regs + GINTSTS);
+       }
+
+       if (gintsts & GINTSTS_INCOMPL_SOOUT) {
+               u32 idx, epctl_reg;
+               struct dwc2_hsotg_ep *hs_ep;
+
+               dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOOUT\n", __func__);
+               for (idx = 1; idx < hsotg->num_of_eps; idx++) {
+                       hs_ep = hsotg->eps_out[idx];
+
+                       if (!hs_ep->isochronous || hs_ep->has_correct_parity)
+                               continue;
+
+                       epctl_reg = DOEPCTL(idx);
+                       dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
+               }
+               dwc2_writel(GINTSTS_INCOMPL_SOOUT, hsotg->regs + GINTSTS);
+       }
+
        /*
         * if we've had fifo events, we should try and go around the
         * loop again to see if there's any point in returning yet.
@@ -2667,6 +2718,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
        hs_ep->periodic = 0;
        hs_ep->halted = 0;
        hs_ep->interval = desc->bInterval;
+       hs_ep->has_correct_parity = 0;
 
        if (hs_ep->interval > 1 && hs_ep->mc > 1)
                dev_err(hsotg->dev, "MC > 1 when interval is not 1\n");
@@ -2823,6 +2875,79 @@ static bool on_list(struct dwc2_hsotg_ep *ep, struct dwc2_hsotg_req *test)
        return false;
 }
 
+static int dwc2_hsotg_wait_bit_set(struct dwc2_hsotg *hs_otg, u32 reg,
+                                                       u32 bit, u32 timeout)
+{
+       u32 i;
+
+       for (i = 0; i < timeout; i++) {
+               if (dwc2_readl(hs_otg->regs + reg) & bit)
+                       return 0;
+               udelay(1);
+       }
+
+       return -ETIMEDOUT;
+}
+
+static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg,
+                                               struct dwc2_hsotg_ep *hs_ep)
+{
+       u32 epctrl_reg;
+       u32 epint_reg;
+
+       epctrl_reg = hs_ep->dir_in ? DIEPCTL(hs_ep->index) :
+               DOEPCTL(hs_ep->index);
+       epint_reg = hs_ep->dir_in ? DIEPINT(hs_ep->index) :
+               DOEPINT(hs_ep->index);
+
+       dev_dbg(hsotg->dev, "%s: stopping transfer on %s\n", __func__,
+                       hs_ep->name);
+       if (hs_ep->dir_in) {
+               __orr32(hsotg->regs + epctrl_reg, DXEPCTL_SNAK);
+               /* Wait for Nak effect */
+               if (dwc2_hsotg_wait_bit_set(hsotg, epint_reg,
+                                               DXEPINT_INEPNAKEFF, 100))
+                       dev_warn(hsotg->dev,
+                               "%s: timeout DIEPINT.NAKEFF\n", __func__);
+       } else {
+               /* Clear any pending nak effect interrupt */
+               dwc2_writel(GINTSTS_GINNAKEFF, hsotg->regs + GINTSTS);
+
+               __orr32(hsotg->regs + DCTL, DCTL_SGNPINNAK);
+
+               /* Wait for global nak to take effect */
+               if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS,
+                                               GINTSTS_GINNAKEFF, 100))
+                       dev_warn(hsotg->dev,
+                               "%s: timeout GINTSTS.GINNAKEFF\n", __func__);
+       }
+
+       /* Disable ep */
+       __orr32(hsotg->regs + epctrl_reg, DXEPCTL_EPDIS | DXEPCTL_SNAK);
+
+       /* Wait for ep to be disabled */
+       if (dwc2_hsotg_wait_bit_set(hsotg, epint_reg, DXEPINT_EPDISBLD, 100))
+               dev_warn(hsotg->dev,
+                       "%s: timeout DOEPCTL.EPDisable\n", __func__);
+
+       if (hs_ep->dir_in) {
+               if (hsotg->dedicated_fifos) {
+                       dwc2_writel(GRSTCTL_TXFNUM(hs_ep->fifo_index) |
+                               GRSTCTL_TXFFLSH, hsotg->regs + GRSTCTL);
+                       /* Wait for fifo flush */
+                       if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL,
+                                                       GRSTCTL_TXFFLSH, 100))
+                               dev_warn(hsotg->dev,
+                                       "%s: timeout flushing fifos\n",
+                                       __func__);
+               }
+               /* TODO: Flush shared tx fifo */
+       } else {
+               /* Remove global NAKs */
+               __bic32(hsotg->regs + DCTL, DCTL_SGNPINNAK);
+       }
+}
+
 /**
  * dwc2_hsotg_ep_dequeue - dequeue given endpoint
  * @ep: The endpoint to dequeue.
@@ -2844,6 +2969,10 @@ static int dwc2_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
                return -EINVAL;
        }
 
+       /* Dequeue already started request */
+       if (req == &hs_ep->req->req)
+               dwc2_hsotg_ep_stop_xfr(hs, hs_ep);
+
        dwc2_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET);
        spin_unlock_irqrestore(&hs->lock, flags);
 
@@ -2943,50 +3072,6 @@ static struct usb_ep_ops dwc2_hsotg_ep_ops = {
        /* note, don't believe we have any call for the fifo routines */
 };
 
-/**
- * dwc2_hsotg_phy_enable - enable platform phy dev
- * @hsotg: The driver state
- *
- * A wrapper for platform code responsible for controlling
- * low-level USB code
- */
-static void dwc2_hsotg_phy_enable(struct dwc2_hsotg *hsotg)
-{
-       struct platform_device *pdev = to_platform_device(hsotg->dev);
-
-       dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
-
-       if (hsotg->uphy)
-               usb_phy_init(hsotg->uphy);
-       else if (hsotg->plat && hsotg->plat->phy_init)
-               hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
-       else {
-               phy_init(hsotg->phy);
-               phy_power_on(hsotg->phy);
-       }
-}
-
-/**
- * dwc2_hsotg_phy_disable - disable platform phy dev
- * @hsotg: The driver state
- *
- * A wrapper for platform code responsible for controlling
- * low-level USB code
- */
-static void dwc2_hsotg_phy_disable(struct dwc2_hsotg *hsotg)
-{
-       struct platform_device *pdev = to_platform_device(hsotg->dev);
-
-       if (hsotg->uphy)
-               usb_phy_shutdown(hsotg->uphy);
-       else if (hsotg->plat && hsotg->plat->phy_exit)
-               hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
-       else {
-               phy_power_off(hsotg->phy);
-               phy_exit(hsotg->phy);
-       }
-}
-
 /**
  * dwc2_hsotg_init - initalize the usb core
  * @hsotg: The driver state
@@ -3060,7 +3145,6 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,
                return -EINVAL;
        }
 
-       mutex_lock(&hsotg->init_mutex);
        WARN_ON(hsotg->driver);
 
        driver->driver.bus = NULL;
@@ -3068,16 +3152,12 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,
        hsotg->gadget.dev.of_node = hsotg->dev->of_node;
        hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 
-       clk_enable(hsotg->clk);
-
-       ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
-                                   hsotg->supplies);
-       if (ret) {
-               dev_err(hsotg->dev, "failed to enable supplies: %d\n", ret);
-               goto err;
+       if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
+               ret = dwc2_lowlevel_hw_enable(hsotg);
+               if (ret)
+                       goto err;
        }
 
-       dwc2_hsotg_phy_enable(hsotg);
        if (!IS_ERR_OR_NULL(hsotg->uphy))
                otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget);
 
@@ -3089,12 +3169,9 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,
 
        dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name);
 
-       mutex_unlock(&hsotg->init_mutex);
-
        return 0;
 
 err:
-       mutex_unlock(&hsotg->init_mutex);
        hsotg->driver = NULL;
        return ret;
 }
@@ -3115,8 +3192,6 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
        if (!hsotg)
                return -ENODEV;
 
-       mutex_lock(&hsotg->init_mutex);
-
        /* all endpoints should be shutdown */
        for (ep = 1; ep < hsotg->num_of_eps; ep++) {
                if (hsotg->eps_in[ep])
@@ -3135,13 +3210,9 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
 
        if (!IS_ERR_OR_NULL(hsotg->uphy))
                otg_set_peripheral(hsotg->uphy->otg, NULL);
-       dwc2_hsotg_phy_disable(hsotg);
-
-       regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
 
-       clk_disable(hsotg->clk);
-
-       mutex_unlock(&hsotg->init_mutex);
+       if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+               dwc2_lowlevel_hw_disable(hsotg);
 
        return 0;
 }
@@ -3169,12 +3240,17 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on)
        struct dwc2_hsotg *hsotg = to_hsotg(gadget);
        unsigned long flags = 0;
 
-       dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on);
+       dev_dbg(hsotg->dev, "%s: is_on: %d op_state: %d\n", __func__, is_on,
+                       hsotg->op_state);
+
+       /* Don't modify pullup state while in host mode */
+       if (hsotg->op_state != OTG_STATE_B_PERIPHERAL) {
+               hsotg->enabled = is_on;
+               return 0;
+       }
 
-       mutex_lock(&hsotg->init_mutex);
        spin_lock_irqsave(&hsotg->lock, flags);
        if (is_on) {
-               clk_enable(hsotg->clk);
                hsotg->enabled = 1;
                dwc2_hsotg_core_init_disconnected(hsotg, false);
                dwc2_hsotg_core_connect(hsotg);
@@ -3182,12 +3258,10 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on)
                dwc2_hsotg_core_disconnect(hsotg);
                dwc2_hsotg_disconnect(hsotg);
                hsotg->enabled = 0;
-               clk_disable(hsotg->clk);
        }
 
        hsotg->gadget.speed = USB_SPEED_UNKNOWN;
        spin_unlock_irqrestore(&hsotg->lock, flags);
-       mutex_unlock(&hsotg->init_mutex);
 
        return 0;
 }
@@ -3200,17 +3274,16 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
        dev_dbg(hsotg->dev, "%s: is_active: %d\n", __func__, is_active);
        spin_lock_irqsave(&hsotg->lock, flags);
 
+       /*
+        * If controller is hibernated, it must exit from hibernation
+        * before being initialized / de-initialized
+        */
+       if (hsotg->lx_state == DWC2_L2)
+               dwc2_exit_hibernation(hsotg, false);
+
        if (is_active) {
-               /*
-                * If controller is hibernated, it must exit from hibernation
-                * before being initialized
-                */
-               if (hsotg->lx_state == DWC2_L2) {
-                       dwc2_exit_hibernation(hsotg, false);
-                       hsotg->lx_state = DWC2_L0;
-               }
-               /* Kill any ep0 requests as controller will be reinitialized */
-               kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
+               hsotg->op_state = OTG_STATE_B_PERIPHERAL;
+
                dwc2_hsotg_core_init_disconnected(hsotg, false);
                if (hsotg->enabled)
                        dwc2_hsotg_core_connect(hsotg);
@@ -3479,17 +3552,11 @@ static inline void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) { }
 int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 {
        struct device *dev = hsotg->dev;
-       struct dwc2_hsotg_plat *plat = dev->platform_data;
        int epnum;
        int ret;
        int i;
        u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE;
 
-       /* Set default UTMI width */
-       hsotg->phyif = GUSBCFG_PHYIF16;
-
-       dwc2_hsotg_of_probe(hsotg);
-
        /* Initialize to legacy fifo configuration values */
        hsotg->g_rx_fifo_sz = 2048;
        hsotg->g_np_g_tx_fifo_sz = 1024;
@@ -3503,70 +3570,14 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
        for (i = 0; i < MAX_EPS_CHANNELS; i++)
                dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i,
                                                hsotg->g_tx_fifo_sz[i]);
-       /*
-        * If platform probe couldn't find a generic PHY or an old style
-        * USB PHY, fall back to pdata
-        */
-       if (IS_ERR_OR_NULL(hsotg->phy) && IS_ERR_OR_NULL(hsotg->uphy)) {
-               plat = dev_get_platdata(dev);
-               if (!plat) {
-                       dev_err(dev,
-                       "no platform data or transceiver defined\n");
-                       return -EPROBE_DEFER;
-               }
-               hsotg->plat = plat;
-       } else if (hsotg->phy) {
-               /*
-                * If using the generic PHY framework, check if the PHY bus
-                * width is 8-bit and set the phyif appropriately.
-                */
-               if (phy_get_bus_width(hsotg->phy) == 8)
-                       hsotg->phyif = GUSBCFG_PHYIF8;
-       }
-
-       hsotg->clk = devm_clk_get(dev, "otg");
-       if (IS_ERR(hsotg->clk)) {
-               hsotg->clk = NULL;
-               dev_dbg(dev, "cannot get otg clock\n");
-       }
 
        hsotg->gadget.max_speed = USB_SPEED_HIGH;
        hsotg->gadget.ops = &dwc2_hsotg_gadget_ops;
        hsotg->gadget.name = dev_name(dev);
        if (hsotg->dr_mode == USB_DR_MODE_OTG)
                hsotg->gadget.is_otg = 1;
-
-       /* reset the system */
-
-       ret = clk_prepare_enable(hsotg->clk);
-       if (ret) {
-               dev_err(dev, "failed to enable otg clk\n");
-               goto err_clk;
-       }
-
-
-       /* regulators */
-
-       for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
-               hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i];
-
-       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies),
-                                hsotg->supplies);
-       if (ret) {
-               dev_err(dev, "failed to request supplies: %d\n", ret);
-               goto err_clk;
-       }
-
-       ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
-                                   hsotg->supplies);
-
-       if (ret) {
-               dev_err(dev, "failed to enable supplies: %d\n", ret);
-               goto err_clk;
-       }
-
-       /* usb phy enable */
-       dwc2_hsotg_phy_enable(hsotg);
+       else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+               hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 
        /*
         * Force Device mode before initialization.
@@ -3585,7 +3596,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
        ret = dwc2_hsotg_hw_cfg(hsotg);
        if (ret) {
                dev_err(hsotg->dev, "Hardware configuration failed: %d\n", ret);
-               goto err_clk;
+               return ret;
        }
 
        dwc2_hsotg_init(hsotg);
@@ -3597,35 +3608,28 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
                        DWC2_CTRL_BUFF_SIZE, GFP_KERNEL);
        if (!hsotg->ctrl_buff) {
                dev_err(dev, "failed to allocate ctrl request buff\n");
-               ret = -ENOMEM;
-               goto err_supplies;
+               return -ENOMEM;
        }
 
        hsotg->ep0_buff = devm_kzalloc(hsotg->dev,
                        DWC2_CTRL_BUFF_SIZE, GFP_KERNEL);
        if (!hsotg->ep0_buff) {
                dev_err(dev, "failed to allocate ctrl reply buff\n");
-               ret = -ENOMEM;
-               goto err_supplies;
+               return -ENOMEM;
        }
 
        ret = devm_request_irq(hsotg->dev, irq, dwc2_hsotg_irq, IRQF_SHARED,
                                dev_name(hsotg->dev), hsotg);
        if (ret < 0) {
-               dwc2_hsotg_phy_disable(hsotg);
-               clk_disable_unprepare(hsotg->clk);
-               regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-                                      hsotg->supplies);
                dev_err(dev, "cannot claim IRQ for gadget\n");
-               goto err_supplies;
+               return ret;
        }
 
        /* hsotg->num_of_eps holds number of EPs other than ep0 */
 
        if (hsotg->num_of_eps == 0) {
                dev_err(dev, "wrong number of EPs (zero)\n");
-               ret = -EINVAL;
-               goto err_supplies;
+               return -EINVAL;
        }
 
        /* setup endpoint information */
@@ -3639,8 +3643,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
                                                     GFP_KERNEL);
        if (!hsotg->ctrl_req) {
                dev_err(dev, "failed to allocate ctrl req\n");
-               ret = -ENOMEM;
-               goto err_supplies;
+               return -ENOMEM;
        }
 
        /* initialise the endpoints now the core has been initialised */
@@ -3653,30 +3656,13 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
                                                                epnum, 0);
        }
 
-       /* disable power and clock */
-       dwc2_hsotg_phy_disable(hsotg);
-
-       ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-                                   hsotg->supplies);
-       if (ret) {
-               dev_err(dev, "failed to disable supplies: %d\n", ret);
-               goto err_supplies;
-       }
-
        ret = usb_add_gadget_udc(dev, &hsotg->gadget);
        if (ret)
-               goto err_supplies;
+               return ret;
 
        dwc2_hsotg_dump(hsotg);
 
        return 0;
-
-err_supplies:
-       dwc2_hsotg_phy_disable(hsotg);
-err_clk:
-       clk_disable_unprepare(hsotg->clk);
-
-       return ret;
 }
 
 /**
@@ -3686,7 +3672,6 @@ err_clk:
 int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg)
 {
        usb_del_gadget_udc(&hsotg->gadget);
-       clk_disable_unprepare(hsotg->clk);
 
        return 0;
 }
@@ -3694,12 +3679,9 @@ int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg)
 int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg)
 {
        unsigned long flags;
-       int ret = 0;
 
        if (hsotg->lx_state != DWC2_L0)
-               return ret;
-
-       mutex_lock(&hsotg->init_mutex);
+               return 0;
 
        if (hsotg->driver) {
                int ep;
@@ -3714,52 +3696,34 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg)
                hsotg->gadget.speed = USB_SPEED_UNKNOWN;
                spin_unlock_irqrestore(&hsotg->lock, flags);
 
-               dwc2_hsotg_phy_disable(hsotg);
-
                for (ep = 0; ep < hsotg->num_of_eps; ep++) {
                        if (hsotg->eps_in[ep])
                                dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
                        if (hsotg->eps_out[ep])
                                dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
                }
-
-               ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-                                            hsotg->supplies);
-               clk_disable(hsotg->clk);
        }
 
-       mutex_unlock(&hsotg->init_mutex);
-
-       return ret;
+       return 0;
 }
 
 int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg)
 {
        unsigned long flags;
-       int ret = 0;
 
        if (hsotg->lx_state == DWC2_L2)
-               return ret;
-
-       mutex_lock(&hsotg->init_mutex);
+               return 0;
 
        if (hsotg->driver) {
                dev_info(hsotg->dev, "resuming usb gadget %s\n",
                         hsotg->driver->driver.name);
 
-               clk_enable(hsotg->clk);
-               ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
-                                           hsotg->supplies);
-
-               dwc2_hsotg_phy_enable(hsotg);
-
                spin_lock_irqsave(&hsotg->lock, flags);
                dwc2_hsotg_core_init_disconnected(hsotg, false);
                if (hsotg->enabled)
                        dwc2_hsotg_core_connect(hsotg);
                spin_unlock_irqrestore(&hsotg->lock, flags);
        }
-       mutex_unlock(&hsotg->init_mutex);
 
-       return ret;
+       return 0;
 }