summaryrefslogtreecommitdiff
path: root/drivers/phy/phy-samsung-usb2.c
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2015-08-21 12:38:37 (GMT)
committerKishon Vijay Abraham I <kishon@ti.com>2015-10-06 14:51:47 (GMT)
commita007ddbaef5317f76bec541688e304f31ad9c4b0 (patch)
treea991e43fb013d8b4397beec3c363aac12a083b44 /drivers/phy/phy-samsung-usb2.c
parent6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f (diff)
downloadlinux-a007ddbaef5317f76bec541688e304f31ad9c4b0.tar.xz
phy: exynos-usb2: add vbus regulator support
Exynos USB2 PHY has separate power supply, which is usually provided by VBUS regulator. This patch adds support for it. VBUS regulator is optional, to keep compatibility with boards, which have VBUS provided from some always-on power source. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy/phy-samsung-usb2.c')
-rw-r--r--drivers/phy/phy-samsung-usb2.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c
index f278a9c..1d22d93 100644
--- a/drivers/phy/phy-samsung-usb2.c
+++ b/drivers/phy/phy-samsung-usb2.c
@@ -27,6 +27,13 @@ static int samsung_usb2_phy_power_on(struct phy *phy)
dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n",
inst->cfg->label);
+
+ if (drv->vbus) {
+ ret = regulator_enable(drv->vbus);
+ if (ret)
+ goto err_regulator;
+ }
+
ret = clk_prepare_enable(drv->clk);
if (ret)
goto err_main_clk;
@@ -48,6 +55,9 @@ err_power_on:
err_instance_clk:
clk_disable_unprepare(drv->clk);
err_main_clk:
+ if (drv->vbus)
+ regulator_disable(drv->vbus);
+err_regulator:
return ret;
}
@@ -55,7 +65,7 @@ static int samsung_usb2_phy_power_off(struct phy *phy)
{
struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy);
struct samsung_usb2_phy_driver *drv = inst->drv;
- int ret;
+ int ret = 0;
dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n",
inst->cfg->label);
@@ -68,7 +78,10 @@ static int samsung_usb2_phy_power_off(struct phy *phy)
}
clk_disable_unprepare(drv->ref_clk);
clk_disable_unprepare(drv->clk);
- return 0;
+ if (drv->vbus)
+ ret = regulator_disable(drv->vbus);
+
+ return ret;
}
static const struct phy_ops samsung_usb2_phy_ops = {
@@ -203,6 +216,14 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
return ret;
}
+ drv->vbus = devm_regulator_get(dev, "vbus");
+ if (IS_ERR(drv->vbus)) {
+ ret = PTR_ERR(drv->vbus);
+ if (ret == -EPROBE_DEFER)
+ return ret;
+ drv->vbus = NULL;
+ }
+
for (i = 0; i < drv->cfg->num_phys; i++) {
char *label = drv->cfg->phys[i].label;
struct samsung_usb2_phy_instance *p = &drv->instances[i];