USB: dwc3_otg: Defer VBUS regulator voting from probe to start_host

VBUS regulator is required only in HOST mode to supply VBUS. Hence,
it is not best idea to bail out from probe if VBUS regulator_get
fails. Additionally, the regulator_get may fail with -517 or
EPROBE_DEFER. In this case driver should ideally return EPROBE_DEFER
which allows kernel to call driver's probe again later. But, this
approach can not be used with OTG driver as there are other
dependent device drivers e.g. android composite gadget and
dwc3_msm which expects OTG to be available. Also, deferring probe
results in userspace bootup scripts to fail which may be required
to configure gadget driver parameters and it would be difficult to
reconfigure these parameters later.
Hence, moving vbus regulator get from driver probe to start_host
to addresses these issues.

Change-Id: I2e1ab1a86d9c1389bca09d7dd9574ef481056ed6
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 1aa8519..41dd144 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -100,11 +100,23 @@
 static int dwc3_otg_start_host(struct usb_otg *otg, int on)
 {
 	struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
+	struct dwc3 *dwc = dotg->dwc;
 	int ret = 0;
 
-	if (!dotg->dwc->xhci)
+	if (!dwc->xhci)
 		return -EINVAL;
 
+	if (!dotg->vbus_otg) {
+		dotg->vbus_otg = devm_regulator_get(dwc->dev->parent,
+							"vbus_dwc3");
+		if (IS_ERR(dotg->vbus_otg)) {
+			dev_err(dwc->dev, "Failed to get vbus regulator\n");
+			ret = PTR_ERR(dotg->vbus_otg);
+			dotg->vbus_otg = 0;
+			return ret;
+		}
+	}
+
 	if (on) {
 		dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
 
@@ -119,7 +131,7 @@
 		 * anymore.
 		 */
 		dwc3_otg_set_host_regs(dotg);
-		ret = platform_device_add(dotg->dwc->xhci);
+		ret = platform_device_add(dwc->xhci);
 		if (ret) {
 			dev_err(otg->phy->dev,
 				"%s: failed to add XHCI pdev ret=%d\n",
@@ -131,7 +143,7 @@
 		ret = regulator_enable(dotg->vbus_otg);
 		if (ret) {
 			dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
-			platform_device_del(dotg->dwc->xhci);
+			platform_device_del(dwc->xhci);
 			return ret;
 		}
 
@@ -140,7 +152,7 @@
 	} else {
 		dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
 
-		platform_device_del(dotg->dwc->xhci);
+		platform_device_del(dwc->xhci);
 
 		ret = regulator_disable(dotg->vbus_otg);
 		if (ret) {
@@ -150,7 +162,7 @@
 		dwc3_otg_notify_host_mode(otg, on);
 
 		/* re-init core and OTG register as XHCI reset clears it */
-		dwc3_post_host_reset_core_init(dotg->dwc);
+		dwc3_post_host_reset_core_init(dwc);
 		dwc3_otg_reset(dotg);
 	}
 
@@ -769,13 +781,6 @@
 		return -ENOMEM;
 	}
 
-	dotg->vbus_otg = devm_regulator_get(dwc->dev->parent, "vbus_dwc3");
-	if (IS_ERR(dotg->vbus_otg)) {
-		dev_err(dwc->dev, "Unable to get vbus_dwc3 regulator\n");
-		ret = PTR_ERR(dotg->vbus_otg);
-		goto err1;
-	}
-
 	/* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
 	dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
 								"otg_irq");