summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-09-02 13:52:53 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-02 13:52:53 -0700
commita48893e20274b9f034349ebb886d55b488611deb (patch)
treeaeefc84e1a92625fa6e2a9132cf0c8bff5a3de85
parent8965988fffb2b7425afcc50d49e9a171ced0df46 (diff)
parentd72551997664fb9d50babf5597039d7a8883afe9 (diff)
Merge "usb: phy: handle phy related regulators properly"
-rw-r--r--drivers/usb/phy/phy-msm-ssusb-qmp.c108
1 files changed, 49 insertions, 59 deletions
diff --git a/drivers/usb/phy/phy-msm-ssusb-qmp.c b/drivers/usb/phy/phy-msm-ssusb-qmp.c
index 529e4ea76a96..87235a5a4f99 100644
--- a/drivers/usb/phy/phy-msm-ssusb-qmp.c
+++ b/drivers/usb/phy/phy-msm-ssusb-qmp.c
@@ -89,6 +89,7 @@ struct msm_ssphy_qmp {
struct clk *pipe_clk;
struct clk *phy_reset;
struct clk *phy_phy_reset;
+ bool power_enabled;
bool clk_enabled;
bool cable_connected;
bool in_suspend;
@@ -159,38 +160,47 @@ static void msm_ssusb_qmp_enable_autonomous(struct msm_ssphy_qmp *phy,
}
}
-
-static int msm_ssusb_qmp_config_vdd(struct msm_ssphy_qmp *phy, int high)
+static int msm_ssusb_qmp_ldo_enable(struct msm_ssphy_qmp *phy, int on)
{
- int min, ret;
+ int min, rc = 0;
- min = high ? 1 : 0; /* low or none? */
- ret = regulator_set_voltage(phy->vdd, phy->vdd_levels[min],
- phy->vdd_levels[2]);
- if (ret) {
- dev_err(phy->phy.dev, "unable to set voltage for ssusb vdd\n");
- return ret;
- }
+ dev_dbg(phy->phy.dev, "reg (%s)\n", on ? "HPM" : "LPM");
- dev_dbg(phy->phy.dev, "min_vol:%d max_vol:%d\n",
- phy->vdd_levels[min], phy->vdd_levels[2]);
- return ret;
-}
+ if (phy->power_enabled == on) {
+ dev_dbg(phy->phy.dev, "PHYs' regulators status %d\n",
+ phy->power_enabled);
+ return 0;
+ }
-static int msm_ssusb_qmp_ldo_enable(struct msm_ssphy_qmp *phy, int on)
-{
- int rc = 0;
+ phy->power_enabled = on;
- dev_dbg(phy->phy.dev, "reg (%s)\n", on ? "HPM" : "LPM");
+ min = on ? 1 : 0; /* low or none? */
if (!on)
goto disable_regulators;
+ rc = regulator_set_voltage(phy->vdd, phy->vdd_levels[min],
+ phy->vdd_levels[2]);
+ if (rc) {
+ dev_err(phy->phy.dev, "unable to set voltage for ssusb vdd\n");
+ return rc;
+ }
+
+ dev_dbg(phy->phy.dev, "min_vol:%d max_vol:%d\n",
+ phy->vdd_levels[min], phy->vdd_levels[2]);
+
+ rc = regulator_enable(phy->vdd);
+ if (rc) {
+ dev_err(phy->phy.dev,
+ "regulator_enable(phy->vdd) failed, ret=%d",
+ rc);
+ goto unconfig_vdd;
+ }
rc = regulator_set_load(phy->core_ldo, USB_SSPHY_HPM_LOAD);
if (rc < 0) {
dev_err(phy->phy.dev, "Unable to set HPM of core_ldo\n");
- return rc;
+ goto disable_vdd;
}
rc = regulator_set_voltage(phy->core_ldo,
@@ -226,6 +236,18 @@ put_core_ldo_lpm:
if (rc < 0)
dev_err(phy->phy.dev, "Unable to set LPM of core_ldo\n");
+disable_vdd:
+ rc = regulator_disable(phy->vdd);
+ if (rc)
+ dev_err(phy->phy.dev, "regulator_disable(phy->vdd) failed, ret=%d",
+ rc);
+
+unconfig_vdd:
+ rc = regulator_set_voltage(phy->vdd, phy->vdd_levels[min],
+ phy->vdd_levels[2]);
+ if (rc)
+ dev_err(phy->phy.dev, "unable to set voltage for ssusb vdd\n");
+
return rc < 0 ? rc : 0;
}
@@ -263,6 +285,14 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy)
if (phy->emulation)
return 0;
+ ret = msm_ssusb_qmp_ldo_enable(phy, 1);
+ if (ret) {
+ dev_err(phy->phy.dev,
+ "msm_ssusb_qmp_ldo_enable(1) failed, ret=%d\n",
+ ret);
+ return ret;
+ }
+
if (!phy->clk_enabled) {
if (phy->ref_clk_src)
clk_prepare_enable(phy->ref_clk_src);
@@ -408,12 +438,6 @@ static int msm_ssphy_power_enable(struct msm_ssphy_qmp *phy, bool on)
*/
if (!host && !phy->cable_connected) {
if (on) {
- ret = regulator_enable(phy->vdd);
- if (ret)
- dev_err(phy->phy.dev,
- "regulator_enable(phy->vdd) failed, ret=%d",
- ret);
-
ret = msm_ssusb_qmp_ldo_enable(phy, 1);
if (ret)
dev_err(phy->phy.dev,
@@ -425,11 +449,6 @@ static int msm_ssphy_power_enable(struct msm_ssphy_qmp *phy, bool on)
dev_err(phy->phy.dev,
"msm_ssusb_qmp_ldo_enable(0) failed, ret=%d\n",
ret);
-
- ret = regulator_disable(phy->vdd);
- if (ret)
- dev_err(phy->phy.dev, "regulator_disable(phy->vdd) failed, ret=%d",
- ret);
}
}
@@ -733,24 +752,6 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev)
goto err;
}
- ret = msm_ssusb_qmp_config_vdd(phy, 1);
- if (ret) {
- dev_err(dev, "ssusb vdd_dig configuration failed\n");
- goto err;
- }
-
- ret = regulator_enable(phy->vdd);
- if (ret) {
- dev_err(dev, "unable to enable the ssusb vdd_dig\n");
- goto unconfig_ss_vdd;
- }
-
- ret = msm_ssusb_qmp_ldo_enable(phy, 1);
- if (ret) {
- dev_err(dev, "ssusb vreg enable failed\n");
- goto disable_ss_vdd;
- }
-
phy->ref_clk_src = devm_clk_get(dev, "ref_clk_src");
if (IS_ERR(phy->ref_clk_src))
phy->ref_clk_src = NULL;
@@ -772,16 +773,7 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev)
phy->phy.type = USB_PHY_TYPE_USB3;
ret = usb_add_phy_dev(&phy->phy);
- if (ret)
- goto disable_ss_ldo;
- return 0;
-disable_ss_ldo:
- msm_ssusb_qmp_ldo_enable(phy, 0);
-disable_ss_vdd:
- regulator_disable(phy->vdd);
-unconfig_ss_vdd:
- msm_ssusb_qmp_config_vdd(phy, 0);
err:
return ret;
}
@@ -799,8 +791,6 @@ static int msm_ssphy_qmp_remove(struct platform_device *pdev)
if (phy->ref_clk_src)
clk_disable_unprepare(phy->ref_clk_src);
msm_ssusb_qmp_ldo_enable(phy, 0);
- regulator_disable(phy->vdd);
- msm_ssusb_qmp_config_vdd(phy, 0);
clk_disable_unprepare(phy->aux_clk);
clk_disable_unprepare(phy->cfg_ahb_clk);
clk_disable_unprepare(phy->pipe_clk);