summaryrefslogtreecommitdiffstats
path: root/arm-tegra-remove-direct-vbus-regulator-control.patch
diff options
context:
space:
mode:
authorKyle McMartin <kyle@redhat.com>2013-07-23 10:59:14 -0400
committerKyle McMartin <kyle@redhat.com>2013-07-23 10:59:14 -0400
commitabe7567c6697c07ce012638369a4e39e2d3de1df (patch)
tree91de1f714a205e11d0943e68bc0c93628535d4ab /arm-tegra-remove-direct-vbus-regulator-control.patch
parentbd472195d6cd7d03e2f8692f75bb3f378ab622cc (diff)
downloadkernel-abe7567c6697c07ce012638369a4e39e2d3de1df.tar.gz
kernel-abe7567c6697c07ce012638369a4e39e2d3de1df.tar.xz
kernel-abe7567c6697c07ce012638369a4e39e2d3de1df.zip
arm-tegra-remove-direct-vbus-regulator-control.patch: backport patches to fix ehci-tegra
Diffstat (limited to 'arm-tegra-remove-direct-vbus-regulator-control.patch')
-rw-r--r--arm-tegra-remove-direct-vbus-regulator-control.patch137
1 files changed, 137 insertions, 0 deletions
diff --git a/arm-tegra-remove-direct-vbus-regulator-control.patch b/arm-tegra-remove-direct-vbus-regulator-control.patch
new file mode 100644
index 000000000..b4fe2c0be
--- /dev/null
+++ b/arm-tegra-remove-direct-vbus-regulator-control.patch
@@ -0,0 +1,137 @@
+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 <asm/mach-types.h>
+ #include <linux/usb/ehci_def.h>
+ #include <linux/usb/tegra_usb_phy.h>
++#include <linux/regulator/consumer.h>
+
+ #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;