diff options
author | Rakesh Bodla <rbodla@nvidia.com> | 2012-06-01 15:14:00 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-06-03 08:06:56 -0700 |
commit | bd44232c77e49bba4f23f5c7dde68a82414c722b (patch) | |
tree | 2e7ea38322e560dad0830dcc9f59d0e56cc8a2a9 /arch/arm/mach-tegra/usb_phy.c | |
parent | fdf40891983fc3fe1942877dcb07a4eab25f1796 (diff) |
ARM: tegra: usb_phy: turn off clocks during suspend
To save power turning off/on clocks (controller, emc, sclk)
appropriately depending upon the features supported on
particular controller.
Bug 991262
Bug 993380
Change-Id: I15fd5641c73f6a170a33515b5e9fe0a62c8430cc
Signed-off-by: Rakesh Bodla <rbodla@nvidia.com>
Reviewed-on: http://git-master/r/105887
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/usb_phy.c')
-rw-r--r-- | arch/arm/mach-tegra/usb_phy.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c index 3074dcfa7ca5..bfb9abae2c94 100644 --- a/arch/arm/mach-tegra/usb_phy.c +++ b/arch/arm/mach-tegra/usb_phy.c @@ -146,9 +146,10 @@ static void tegra_usb_phy_release_clocks(struct tegra_usb_phy *phy) { clk_put(phy->emc_clk); clk_put(phy->sys_clk); - if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST && - phy->pdata->u_data.host.hot_plug) - clk_disable(phy->ctrlr_clk); + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) + if (phy->pdata->u_data.host.hot_plug || + phy->pdata->u_data.host.remote_wakeup_supported) + clk_disable(phy->ctrlr_clk); clk_put(phy->ctrlr_clk); clk_disable(phy->pllu_clk); clk_put(phy->pllu_clk); @@ -173,9 +174,10 @@ static int tegra_usb_phy_get_clocks(struct tegra_usb_phy *phy) goto fail_ctrlr_clk; } - if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST && - phy->pdata->u_data.host.hot_plug) - clk_enable(phy->ctrlr_clk); + if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) + if (phy->pdata->u_data.host.hot_plug || + phy->pdata->u_data.host.remote_wakeup_supported) + clk_enable(phy->ctrlr_clk); phy->sys_clk = clk_get(&phy->pdev->dev, "sclk"); if (IS_ERR(phy->sys_clk)) { @@ -396,8 +398,6 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy) } } - tegra_usb_phy_release_clocks(phy); - if (phy->vdd_reg) { regulator_disable(phy->vdd_reg); regulator_put(phy->vdd_reg); @@ -409,6 +409,8 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy) if (phy->pdata->ops && phy->pdata->ops->close) phy->pdata->ops->close(); + tegra_usb_phy_release_clocks(phy); + kfree(phy->pdata); kfree(phy); } @@ -457,7 +459,8 @@ int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) clk_disable(phy->emc_clk); clk_disable(phy->sys_clk); if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) { - if (!phy->pdata->u_data.host.hot_plug) + if (!phy->pdata->u_data.host.hot_plug && + !phy->pdata->u_data.host.remote_wakeup_supported) clk_disable(phy->ctrlr_clk); } else { /* In device mode clock is turned on by pmu irq handler @@ -487,7 +490,8 @@ int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) * if pmu irq is not available clocks will not be turned off/on */ if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) { - if (!phy->pdata->u_data.host.hot_plug) + if (!phy->pdata->u_data.host.hot_plug && + !phy->pdata->u_data.host.remote_wakeup_supported) clk_enable(phy->ctrlr_clk); } else { if (phy->pdata->u_data.dev.vbus_pmu_irq && @@ -546,11 +550,7 @@ int tegra_usb_phy_suspend(struct tegra_usb_phy *phy) err = phy->ops->suspend(phy); if (!err && phy->pdata->u_data.host.power_off_on_suspend) { - if (phy->pdata->ops && phy->pdata->ops->pre_phy_off) - phy->pdata->ops->pre_phy_off(); - err = phy->ops->power_off(phy); - if (phy->pdata->ops && phy->pdata->ops->post_phy_off) - phy->pdata->ops->post_phy_off(); + tegra_usb_phy_power_off(phy); } return err; @@ -590,11 +590,7 @@ int tegra_usb_phy_resume(struct tegra_usb_phy *phy) DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); if (phy->pdata->u_data.host.power_off_on_suspend) { - if (phy->pdata->ops && phy->pdata->ops->pre_phy_on) - phy->pdata->ops->pre_phy_on(); - err = phy->ops->power_on(phy); - if (phy->pdata->ops && phy->pdata->ops->post_phy_on) - phy->pdata->ops->post_phy_on(); + tegra_usb_phy_power_on(phy); } if (!err && phy->ops && phy->ops->resume) |