usb: musb: mediatek: add support for vbus-supply regulator

Add the ability to control a regulator for VBUS. The regulator
will be enabled only when we are in host mode.

Signed-off-by: Fabien Parent <fparent@baylibre.com>
Change-Id: Ief542dd0b95fcab572a422315d13d5ef391de062
diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c
index e218dc0..0582041 100644
--- a/drivers/usb/musb/mediatek.c
+++ b/drivers/usb/musb/mediatek.c
@@ -52,6 +52,7 @@
 	struct clk *univpll;
 	enum usb_role role;
 	struct usb_role_switch *role_sw;
+	struct regulator *vbus_supply;
 };
 
 static int mtk_musb_clks_get(struct mtk_glue *glue)
@@ -124,10 +125,14 @@
 	struct musb *musb = glue->musb;
 	u8 devctl = readb(musb->mregs + MUSB_DEVCTL);
 	enum usb_role new_role;
+	int ret;
 
 	if (role == glue->role)
 		return 0;
 
+	if (glue->vbus_supply && regulator_is_enabled(glue->vbus_supply))
+		regulator_disable(glue->vbus_supply);
+
 	switch (role) {
 	case USB_ROLE_HOST:
 		musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
@@ -138,6 +143,14 @@
 
 		devctl |= MUSB_DEVCTL_SESSION;
 		musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+		if (glue->vbus_supply) {
+			ret = regulator_enable(glue->vbus_supply);
+			if (ret)
+				dev_warn(glue->dev,
+					 "Failed to enable VBUS: %d\n", ret);
+		}
+
 		MUSB_HST_MODE(musb);
 		break;
 	case USB_ROLE_DEVICE:
@@ -526,6 +539,8 @@
 		goto err_unregister_usb_phy;
 	}
 
+	glue->vbus_supply = devm_regulator_get_optional(dev, "vbus");
+
 	platform_set_drvdata(pdev, glue);
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);