}
 }
 
+/* Must NOT be called with interrupt disabled or spinlock held */
+static void dwc2_port_resume(struct dwc2_hsotg *hsotg)
+{
+       unsigned long flags;
+       u32 hprt0;
+       u32 pcgctl;
+
+       /* Resume the Phy Clock */
+       pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
+       pcgctl &= ~PCGCTL_STOPPCLK;
+       dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
+       usleep_range(20000, 40000);
+
+       spin_lock_irqsave(&hsotg->lock, flags);
+       hprt0 = dwc2_read_hprt0(hsotg);
+       hprt0 |= HPRT0_RES;
+       hprt0 &= ~HPRT0_SUSP;
+       dwc2_writel(hprt0, hsotg->regs + HPRT0);
+       spin_unlock_irqrestore(&hsotg->lock, flags);
+
+       msleep(USB_RESUME_TIMEOUT);
+
+       spin_lock_irqsave(&hsotg->lock, flags);
+       hprt0 = dwc2_read_hprt0(hsotg);
+       hprt0 &= ~(HPRT0_RES | HPRT0_SUSP);
+       dwc2_writel(hprt0, hsotg->regs + HPRT0);
+       spin_unlock_irqrestore(&hsotg->lock, flags);
+}
+
 /* Handles hub class-specific requests */
 static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
                                u16 wvalue, u16 windex, char *buf, u16 wlength)
                case USB_PORT_FEAT_SUSPEND:
                        dev_dbg(hsotg->dev,
                                "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
-                       dwc2_writel(0, hsotg->regs + PCGCTL);
-                       usleep_range(20000, 40000);
 
-                       hprt0 = dwc2_read_hprt0(hsotg);
-                       hprt0 |= HPRT0_RES;
-                       dwc2_writel(hprt0, hsotg->regs + HPRT0);
-                       hprt0 &= ~HPRT0_SUSP;
-                       msleep(USB_RESUME_TIMEOUT);
-
-                       hprt0 &= ~HPRT0_RES;
-                       dwc2_writel(hprt0, hsotg->regs + HPRT0);
+                       dwc2_port_resume(hsotg);
                        break;
 
                case USB_PORT_FEAT_POWER: