summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/phy/phy-twl4030-usb.c72
1 files changed, 31 insertions, 41 deletions
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index a292db01b503..519cc909b25a 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -383,45 +383,6 @@ static void __twl4030_phy_power(struct twl4030_usb *twl, int on)
WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
}
-static void twl4030_phy_power(struct twl4030_usb *twl, int on)
-{
- int ret;
-
- if (on) {
- ret = regulator_enable(twl->usb3v1);
- if (ret)
- dev_err(twl->dev, "Failed to enable usb3v1\n");
-
- ret = regulator_enable(twl->usb1v8);
- if (ret)
- dev_err(twl->dev, "Failed to enable usb1v8\n");
-
- /*
- * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP
- * in twl4030) resets the VUSB_DEDICATED2 register. This reset
- * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to
- * SLEEP. We work around this by clearing the bit after usv3v1
- * is re-activated. This ensures that VUSB3V1 is really active.
- */
- twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);
-
- ret = regulator_enable(twl->usb1v5);
- if (ret)
- dev_err(twl->dev, "Failed to enable usb1v5\n");
-
- __twl4030_phy_power(twl, 1);
- twl4030_usb_write(twl, PHY_CLK_CTRL,
- twl4030_usb_read(twl, PHY_CLK_CTRL) |
- (PHY_CLK_CTRL_CLOCKGATING_EN |
- PHY_CLK_CTRL_CLK32K_EN));
- } else {
- __twl4030_phy_power(twl, 0);
- regulator_disable(twl->usb1v5);
- regulator_disable(twl->usb1v8);
- regulator_disable(twl->usb3v1);
- }
-}
-
static int twl4030_usb_runtime_suspend(struct device *dev)
{
struct twl4030_usb *twl = dev_get_drvdata(dev);
@@ -430,7 +391,10 @@ static int twl4030_usb_runtime_suspend(struct device *dev)
if (twl->asleep)
return 0;
- twl4030_phy_power(twl, 0);
+ __twl4030_phy_power(twl, 0);
+ regulator_disable(twl->usb1v5);
+ regulator_disable(twl->usb1v8);
+ regulator_disable(twl->usb3v1);
twl->asleep = 1;
return 0;
@@ -439,12 +403,38 @@ static int twl4030_usb_runtime_suspend(struct device *dev)
static int twl4030_usb_runtime_resume(struct device *dev)
{
struct twl4030_usb *twl = dev_get_drvdata(dev);
+ int res;
dev_dbg(twl->dev, "%s\n", __func__);
if (!twl->asleep)
return 0;
- twl4030_phy_power(twl, 1);
+ res = regulator_enable(twl->usb3v1);
+ if (res)
+ dev_err(twl->dev, "Failed to enable usb3v1\n");
+
+ res = regulator_enable(twl->usb1v8);
+ if (res)
+ dev_err(twl->dev, "Failed to enable usb1v8\n");
+
+ /*
+ * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP
+ * in twl4030) resets the VUSB_DEDICATED2 register. This reset
+ * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to
+ * SLEEP. We work around this by clearing the bit after usv3v1
+ * is re-activated. This ensures that VUSB3V1 is really active.
+ */
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);
+
+ res = regulator_enable(twl->usb1v5);
+ if (res)
+ dev_err(twl->dev, "Failed to enable usb1v5\n");
+
+ __twl4030_phy_power(twl, 1);
+ twl4030_usb_write(twl, PHY_CLK_CTRL,
+ twl4030_usb_read(twl, PHY_CLK_CTRL) |
+ (PHY_CLK_CTRL_CLOCKGATING_EN |
+ PHY_CLK_CTRL_CLK32K_EN));
twl->asleep = 0;
return 0;