summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Lin <stlin@nvidia.com>2011-08-02 15:16:27 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:48:02 -0800
commitee15e3c928970e586556f9bc7126e56bb5ca2f1a (patch)
tree386fa3cba93dbfdbeb05c089c5f003c61b9f5c59
parent7bbb45285a0cc99448ea80fcc6a64bf10dd60b26 (diff)
arm: tegra: usb: add callback functions for null phy power off
Adding pre_phy_off and post_phy_off callback functions in null_phy_power_off function. So that the modem handshaking GPIO is set to reflect the real phy status. Bug 856096 Bug 854339 Original-Change-Id: I6f4ce9d6072d550c4f02c7fc3bd9c601f05822ab Reviewed-on: http://git-master/r/44634 Tested-by: Szming Lin <stlin@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Rebase-Id: R6f086d6d1608f961fcffe136ed6ff5f0a3646303
-rw-r--r--arch/arm/mach-tegra/include/mach/usb_phy.h6
-rw-r--r--arch/arm/mach-tegra/usb_phy.c26
2 files changed, 21 insertions, 11 deletions
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
index 30160d63cc41..bad62c68df71 100644
--- a/arch/arm/mach-tegra/include/mach/usb_phy.h
+++ b/arch/arm/mach-tegra/include/mach/usb_phy.h
@@ -45,8 +45,10 @@ struct tegra_ulpi_config {
int reset_gpio;
const char *clk;
const struct tegra_ulpi_trimmer *trimmer;
- int (*preinit)(void);
- int (*postinit)(void);
+ int (*pre_phy_on)(void);
+ int (*post_phy_on)(void);
+ int (*pre_phy_off)(void);
+ int (*post_phy_off)(void);
};
struct tegra_uhsic_config {
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index 50de697f32e7..a7fe6e21f5d4 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -1033,9 +1033,13 @@ static void utmi_phy_restore_end(struct tegra_usb_phy *phy)
static void ulpi_set_tristate(bool enable)
{
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
int tristate = (enable)? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL;
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate);
+#else
tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA0, tristate);
tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA1, tristate);
tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA2, tristate);
@@ -1105,9 +1109,7 @@ static void ulpi_phy_restore_start(struct tegra_usb_phy *phy,
void __iomem *base = phy->regs;
/*Tristate ulpi interface before USB controller resume*/
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, TEGRA_TRI_TRISTATE);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, TEGRA_TRI_TRISTATE);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, TEGRA_TRI_TRISTATE);
+ ulpi_set_tristate(true);
val = readl(base + ULPI_TIMING_CTRL_0);
val &= ~ULPI_OUTPUT_PINMUX_BYP;
@@ -1125,9 +1127,7 @@ static void ulpi_phy_restore_end(struct tegra_usb_phy *phy)
val |= ULPI_OUTPUT_PINMUX_BYP;
writel(val, base + ULPI_TIMING_CTRL_0);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, TEGRA_TRI_NORMAL);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, TEGRA_TRI_NORMAL);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, TEGRA_TRI_NORMAL);
+ ulpi_set_tristate(false);
#endif
}
@@ -1278,7 +1278,7 @@ static int null_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
ulpi_set_host(base);
- if (config->preinit && config->preinit())
+ if (config->pre_phy_on && config->pre_phy_on())
return -EAGAIN;
val = readl(base + USB_SUSP_CTRL);
@@ -1362,7 +1362,7 @@ static int null_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
writel(val, base + ULPI_TIMING_CTRL_0);
udelay(10);
- if (config->postinit && config->postinit())
+ if (config->post_phy_on && config->post_phy_on())
return -EAGAIN;
return 0;
@@ -1372,12 +1372,20 @@ static int null_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
+ struct tegra_ulpi_config *config = phy->config;
+
+ if (config->pre_phy_off && config->pre_phy_off())
+ return -EAGAIN;
val = readl(base + ULPI_TIMING_CTRL_0);
val &= ~ULPI_CLK_PADOUT_ENA;
writel(val, base + ULPI_TIMING_CTRL_0);
ulpi_set_tristate(true);
+
+ if (config->post_phy_off && config->post_phy_off())
+ return -EAGAIN;
+
return 0;
}