Kyle McMartin abe7567
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
Kyle McMartin abe7567
index 6ee7ef7..14c1f35 100644
Kyle McMartin abe7567
--- a/drivers/usb/host/ehci-tegra.c
Kyle McMartin abe7567
+++ b/drivers/usb/host/ehci-tegra.c
Kyle McMartin abe7567
@@ -322,33 +322,6 @@ static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
Kyle McMartin abe7567
 	free_dma_aligned_buffer(urb);
Kyle McMartin abe7567
 }
Kyle McMartin abe7567
 
Kyle McMartin abe7567
-static int setup_vbus_gpio(struct platform_device *pdev,
Kyle McMartin abe7567
-			   struct tegra_ehci_platform_data *pdata)
Kyle McMartin abe7567
-{
Kyle McMartin abe7567
-	int err = 0;
Kyle McMartin abe7567
-	int gpio;
Kyle McMartin abe7567
-
Kyle McMartin abe7567
-	gpio = pdata->vbus_gpio;
Kyle McMartin abe7567
-	if (!gpio_is_valid(gpio))
Kyle McMartin abe7567
-		gpio = of_get_named_gpio(pdev->dev.of_node,
Kyle McMartin abe7567
-					 "nvidia,vbus-gpio", 0);
Kyle McMartin abe7567
-	if (!gpio_is_valid(gpio))
Kyle McMartin abe7567
-		return 0;
Kyle McMartin abe7567
-
Kyle McMartin abe7567
-	err = gpio_request(gpio, "vbus_gpio");
Kyle McMartin abe7567
-	if (err) {
Kyle McMartin abe7567
-		dev_err(&pdev->dev, "can't request vbus gpio %d", gpio);
Kyle McMartin abe7567
-		return err;
Kyle McMartin abe7567
-	}
Kyle McMartin abe7567
-	err = gpio_direction_output(gpio, 1);
Kyle McMartin abe7567
-	if (err) {
Kyle McMartin abe7567
-		dev_err(&pdev->dev, "can't enable vbus\n");
Kyle McMartin abe7567
-		return err;
Kyle McMartin abe7567
-	}
Kyle McMartin abe7567
-
Kyle McMartin abe7567
-	return err;
Kyle McMartin abe7567
-}
Kyle McMartin abe7567
-
Kyle McMartin abe7567
 static int tegra_ehci_probe(struct platform_device *pdev)
Kyle McMartin abe7567
 {
Kyle McMartin abe7567
 	struct resource *res;
Kyle McMartin abe7567
@@ -376,14 +349,11 @@ static int tegra_ehci_probe(struct platform_device *pdev)
Kyle McMartin abe7567
 	if (!pdev->dev.coherent_dma_mask)
Kyle McMartin abe7567
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
Kyle McMartin abe7567
 
Kyle McMartin abe7567
-	setup_vbus_gpio(pdev, pdata);
Kyle McMartin abe7567
-
Kyle McMartin abe7567
 	hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev,
Kyle McMartin abe7567
 					dev_name(&pdev->dev));
Kyle McMartin abe7567
 	if (!hcd) {
Kyle McMartin abe7567
 		dev_err(&pdev->dev, "Unable to create HCD\n");
Kyle McMartin abe7567
-		err = -ENOMEM;
Kyle McMartin abe7567
-		goto cleanup_vbus_gpio;
Kyle McMartin abe7567
+		return -ENOMEM;
Kyle McMartin abe7567
 	}
Kyle McMartin abe7567
 	platform_set_drvdata(pdev, hcd);
Kyle McMartin abe7567
 	ehci = hcd_to_ehci(hcd);
Kyle McMartin abe7567
@@ -494,8 +464,6 @@ cleanup_clk_get:
Kyle McMartin abe7567
 	clk_put(tegra->clk);
Kyle McMartin abe7567
 cleanup_hcd_create:
Kyle McMartin abe7567
 	usb_put_hcd(hcd);
Kyle McMartin abe7567
-cleanup_vbus_gpio:
Kyle McMartin abe7567
-	/* FIXME: Undo setup_vbus_gpio() here */
Kyle McMartin abe7567
 	return err;
Kyle McMartin abe7567
 }
Kyle McMartin abe7567
 
Kyle McMartin abe7567
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
Kyle McMartin abe7567
index cec0855..b3b4809 100644
Kyle McMartin abe7567
--- a/drivers/usb/phy/phy-tegra-usb.c
Kyle McMartin abe7567
+++ b/drivers/usb/phy/phy-tegra-usb.c
Kyle McMartin abe7567
@@ -34,6 +34,7 @@
Kyle McMartin abe7567
 #include <asm/mach-types.h>
Kyle McMartin abe7567
 #include <linux/usb/ehci_def.h>
Kyle McMartin abe7567
 #include <linux/usb/tegra_usb_phy.h>
Kyle McMartin abe7567
+#include <linux/regulator/consumer.h>
Kyle McMartin abe7567
 
Kyle McMartin abe7567
 #define ULPI_VIEWPORT		0x170
Kyle McMartin abe7567
 
Kyle McMartin abe7567
@@ -237,12 +238,24 @@ static int utmip_pad_open(struct tegra_usb_phy *phy)
Kyle McMartin abe7567
 		return PTR_ERR(phy->pad_clk);
Kyle McMartin abe7567
 	}
Kyle McMartin abe7567
 
Kyle McMartin abe7567
+	phy->vbus = devm_regulator_get(phy->dev, "vbus");
Kyle McMartin abe7567
+	/* On some boards, the VBUS regulator doesn't need to be controlled */
Kyle McMartin abe7567
+	if (IS_ERR(phy->vbus)) {
Kyle McMartin abe7567
+		if (PTR_ERR(phy->vbus) == -ENODEV) {
Kyle McMartin abe7567
+			dev_notice(phy->dev, "no vbus regulator");
Kyle McMartin abe7567
+			phy->vbus = NULL;
Kyle McMartin abe7567
+		} else {
Kyle McMartin abe7567
+			return PTR_ERR(phy->vbus);
Kyle McMartin abe7567
+		}
Kyle McMartin abe7567
+	}
Kyle McMartin abe7567
+
Kyle McMartin abe7567
 	return 0;
Kyle McMartin abe7567
 }
Kyle McMartin abe7567
 
Kyle McMartin abe7567
 static void utmip_pad_power_on(struct tegra_usb_phy *phy)
Kyle McMartin abe7567
 {
Kyle McMartin abe7567
 	unsigned long val, flags;
Kyle McMartin abe7567
+	int err;
Kyle McMartin abe7567
 	void __iomem *base = phy->pad_regs;
Kyle McMartin abe7567
 
Kyle McMartin abe7567
 	clk_prepare_enable(phy->pad_clk);
Kyle McMartin abe7567
@@ -258,6 +271,14 @@ static void utmip_pad_power_on(struct tegra_usb_phy *phy)
Kyle McMartin abe7567
 	spin_unlock_irqrestore(&utmip_pad_lock, flags);
Kyle McMartin abe7567
 
Kyle McMartin abe7567
 	clk_disable_unprepare(phy->pad_clk);
Kyle McMartin abe7567
+
Kyle McMartin abe7567
+	if (phy->vbus) {
Kyle McMartin abe7567
+		err = regulator_enable(phy->vbus);
Kyle McMartin abe7567
+		if (err)
Kyle McMartin abe7567
+			dev_err(phy->dev,
Kyle McMartin abe7567
+				"failed to enable usb vbus regulator: %d\n",
Kyle McMartin abe7567
+				err);
Kyle McMartin abe7567
+	}
Kyle McMartin abe7567
 }
Kyle McMartin abe7567
 
Kyle McMartin abe7567
 static int utmip_pad_power_off(struct tegra_usb_phy *phy)
Kyle McMartin abe7567
@@ -284,6 +305,9 @@ static int utmip_pad_power_off(struct tegra_usb_phy *phy)
Kyle McMartin abe7567
 
Kyle McMartin abe7567
 	clk_disable_unprepare(phy->pad_clk);
Kyle McMartin abe7567
 
Kyle McMartin abe7567
+	if (phy->vbus)
Kyle McMartin abe7567
+		regulator_disable(phy->vbus);
Kyle McMartin abe7567
+
Kyle McMartin abe7567
 	return 0;
Kyle McMartin abe7567
 }
Kyle McMartin abe7567
 
Kyle McMartin abe7567
diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h
Kyle McMartin abe7567
index d2ca919..2b5fa94 100644
Kyle McMartin abe7567
--- a/include/linux/usb/tegra_usb_phy.h
Kyle McMartin abe7567
+++ b/include/linux/usb/tegra_usb_phy.h
Kyle McMartin abe7567
@@ -55,6 +55,7 @@ struct tegra_usb_phy {
Kyle McMartin abe7567
 	struct clk *clk;
Kyle McMartin abe7567
 	struct clk *pll_u;
Kyle McMartin abe7567
 	struct clk *pad_clk;
Kyle McMartin abe7567
+	struct regulator *vbus;
Kyle McMartin abe7567
 	enum tegra_usb_phy_mode mode;
Kyle McMartin abe7567
 	void *config;
Kyle McMartin abe7567
 	struct usb_phy *ulpi;