USB: msm_otg: Set PHCD bit if its not set by the controller during suspend

PHCD bit is automatically set by controller when SUSP bit is set in PORTSC
in Host mode. SUSP bit of PORTSC is set only when a device attached on the
root hub is suspended.

So during host mode suspend, set the PHCD bit if its not set by the
controller automatically.

Change-Id: I37aaab766d8f8eb658ae6fbeaf04be338e507fed
Signed-off-by: Rajkumar Raghupathy <raghup@codeaurora.org>
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index dc3ff26..79a2858 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -591,6 +591,7 @@
 	bool session_active;
 	u32 phy_ctrl_val = 0;
 	unsigned ret;
+	u32 portsc;
 
 	if (atomic_read(&motg->in_lpm))
 		return 0;
@@ -632,17 +633,21 @@
 		motg->lpm_flags |= PHY_OTG_COMP_DISABLED;
 	}
 
-	/*
+	/* Set the PHCD bit, only if it is not set by the controller.
 	 * PHY may take some time or even fail to enter into low power
 	 * mode (LPM). Hence poll for 500 msec and reset the PHY and link
 	 * in failure case.
 	 */
-	writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC);
-	while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
-		if (readl(USB_PORTSC) & PORTSC_PHCD)
-			break;
-		udelay(1);
-		cnt++;
+	portsc = readl_relaxed(USB_PORTSC);
+	if (!(portsc & PORTSC_PHCD)) {
+		writel_relaxed(portsc | PORTSC_PHCD,
+				USB_PORTSC);
+		while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
+			if (readl_relaxed(USB_PORTSC) & PORTSC_PHCD)
+				break;
+			udelay(1);
+			cnt++;
+		}
 	}
 
 	if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) {