summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/usb_phy.c
diff options
context:
space:
mode:
authorRakesh Bodla <rbodla@nvidia.com>2012-06-01 15:14:00 +0530
committerSimone Willett <swillett@nvidia.com>2012-06-03 08:06:56 -0700
commitbd44232c77e49bba4f23f5c7dde68a82414c722b (patch)
tree2e7ea38322e560dad0830dcc9f59d0e56cc8a2a9 /arch/arm/mach-tegra/usb_phy.c
parentfdf40891983fc3fe1942877dcb07a4eab25f1796 (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.c36
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)