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