USB: dwc3_otg: Serialize processing of external events to OTG

Some hardware may support very short or no debounce time to
report USB cable connect events. Using a bad cable or inserting
the cable very slowly can result in OTG events getting fired
rapidly. Existing design may result in processing of events
in parallel or out of order during such scenarios under stress
testing. Fix this in OTG driver by making sure that it starts
processing of a new event only after it is done with previous one.
Also, change dwc3-msm driver to always use workqueue when reporting
external events to OTG.

Change-Id: I309ac51f432731229024b9bf85b3d2f2bf8f8d7f
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index 4980337..8bdaa5d 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -373,6 +373,10 @@
 	struct usb_phy *phy = dotg->otg.phy;
 	int ret = 0;
 
+	/* Flush processing any pending events before handling new ones */
+	if (init)
+		flush_work(&dotg->sm_work);
+
 	if (event == DWC3_EVENT_PHY_RESUME) {
 		if (!pm_runtime_status_suspended(phy->dev)) {
 			dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
@@ -394,6 +398,12 @@
 			}
 		}
 	} else if (event == DWC3_EVENT_XCEIV_STATE) {
+		if (pm_runtime_status_suspended(phy->dev)) {
+			dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
+			ret = pm_runtime_get(phy->dev);
+			if (ret < 0)
+				dev_warn(phy->dev, "pm_runtime_get failed!!\n");
+		}
 		if (ext_xceiv->id == DWC3_ID_FLOAT) {
 			dev_dbg(phy->dev, "XCVR: ID set\n");
 			set_bit(ID, &dotg->inputs);