FROMLIST: usb: dwc2: assert phy reset when waking up in rk3288 platform
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc2 / core_intr.c
index 27daa42788b1a4ab2ac74200d15d8b1a6f212f38..93309d7452edef6d69cf8b48e536ea50a075f6c1 100644 (file)
@@ -347,6 +347,7 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
 static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 {
        int ret;
+       struct device_node *np = hsotg->dev->of_node;
        dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n");
        dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);
 
@@ -378,6 +379,18 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
                        /* Restart the Phy Clock */
                        pcgcctl &= ~PCGCTL_STOPPCLK;
                        dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
+
+                       /*
+                        * It is a quirk in Rockchip RK3288, causing by
+                        * a hardware bug. This will propagate out and
+                        * eventually we'll re-enumerate the device.
+                        * Not great but the best we can do.
+                        */
+                       if (of_device_is_compatible(np, "rockchip,rk3288-usb")) {
+                               /* FIXME: wkp_timer might run early than phy_rst_work */
+                               schedule_work(&hsotg->phy_rst_work);
+                       }
+
                        mod_timer(&hsotg->wkp_timer,
                                  jiffies + msecs_to_jiffies(71));
                } else {