summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuresh Mangipudi <smangipudi@nvidia.com>2011-05-06 13:57:20 +0530
committerNiket Sirsi <nsirsi@nvidia.com>2011-05-19 17:49:40 -0700
commitc20a54d503e859b8b9c62c6fb446fcfe273d433b (patch)
treecd62bf6bf64f77c482f560c67b902889e0773827
parentee550c20967fccfae7b13f2fac6271ae17339f53 (diff)
usb: host: tegra: hotplug detection of device
Add support for usb hotplug, this change will add the following: vbus is left enabled. Bug 796158 Change-Id: I3c3cfa0bf8858b3be2351fe753ceb2a0229ed15d Reviewed-on: http://git-master/r/30686 Reviewed-by: Suresh Mangipudi <smangipudi@nvidia.com> Tested-by: Suresh Mangipudi <smangipudi@nvidia.com> Reviewed-by: Hanumanth Venkateswa Moganty <vmoganty@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: Prashant Gaikwad <pgaikwad@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/include/mach/usb_phy.h8
-rw-r--r--arch/arm/mach-tegra/usb_phy.c107
-rw-r--r--drivers/usb/gadget/fsl_tegra_udc.c11
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c16
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.h8
-rw-r--r--drivers/usb/host/ehci-tegra.c74
-rw-r--r--drivers/usb/otg/tegra-otg.c1
7 files changed, 123 insertions, 102 deletions
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
index f805ca5d0795..0ff8f5545d31 100644
--- a/arch/arm/mach-tegra/include/mach/usb_phy.h
+++ b/arch/arm/mach-tegra/include/mach/usb_phy.h
@@ -99,17 +99,17 @@ struct tegra_usb_phy {
struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
void *config, enum tegra_usb_phy_mode phy_mode);
-int tegra_usb_phy_power_on(struct tegra_usb_phy *phy);
+int tegra_usb_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd);
void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy);
void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy);
-void tegra_usb_phy_power_off(struct tegra_usb_phy *phy);
+void tegra_usb_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd);
-void tegra_usb_phy_preresume(struct tegra_usb_phy *phy);
+void tegra_usb_phy_preresume(struct tegra_usb_phy *phy, bool is_dpd);
-void tegra_usb_phy_postresume(struct tegra_usb_phy *phy);
+void tegra_usb_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd);
void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
enum tegra_usb_phy_port_speed port_speed);
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index 47e0155cc80a..371f5f72dd0f 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -67,6 +67,7 @@
#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
#define USB_SUSP_CLR (1 << 5)
#define USB_PHY_CLK_VALID (1 << 7)
+#define USB_PHY_CLK_VALID_INT_ENB (1 << 9)
#define UTMIP_RESET (1 << 11)
#define UHSIC_RESET (1 << 11)
#define UTMIP_PHY_ENABLE (1 << 12)
@@ -395,7 +396,7 @@ static void utmip_pad_power_on(struct tegra_usb_phy *phy)
clk_disable(phy->pad_clk);
}
-static int utmip_pad_power_off(struct tegra_usb_phy *phy)
+static int utmip_pad_power_off(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val, flags;
void __iomem *base = phy->pad_regs;
@@ -409,7 +410,7 @@ static int utmip_pad_power_off(struct tegra_usb_phy *phy)
spin_lock_irqsave(&utmip_pad_lock, flags);
- if (--utmip_pad_count == 0) {
+ if (--utmip_pad_count == 0 && is_dpd) {
val = readl(base + UTMIP_BIAS_CFG0);
val |= UTMIP_OTGPD | UTMIP_BIASPD;
writel(val, base + UTMIP_BIAS_CFG0);
@@ -521,7 +522,7 @@ static void vbus_disable(int gpio)
gpio_free(gpio);
}
-static int utmi_phy_power_on(struct tegra_usb_phy *phy)
+static int utmi_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
@@ -650,24 +651,15 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
val &= ~USB_PORTSC1_PTS(~0);
writel(val, base + USB_PORTSC1);
}
- if (phy->mode == TEGRA_USB_PHY_MODE_HOST) {
- vbus_enable(usb_phy_data[phy->instance].vbus_gpio);
- }
return 0;
}
-static void utmi_phy_power_off(struct tegra_usb_phy *phy)
+static void utmi_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
- utmi_phy_clk_disable(phy);
-
- if (phy->mode == TEGRA_USB_PHY_MODE_HOST) {
- vbus_disable(usb_phy_data[phy->instance].vbus_gpio);
- }
-
if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
val = readl(base + USB_SUSP_CTRL);
val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0);
@@ -675,30 +667,32 @@ static void utmi_phy_power_off(struct tegra_usb_phy *phy)
writel(val, base + USB_SUSP_CTRL);
}
- val = readl(base + USB_SUSP_CTRL);
- val |= UTMIP_RESET;
- writel(val, base + USB_SUSP_CTRL);
-
- if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
- val = readl(base + UTMIP_BAT_CHRG_CFG0);
- val |= UTMIP_PD_CHRG;
- writel(val, base + UTMIP_BAT_CHRG_CFG0);
- }
-
- val = readl(base + UTMIP_XCVR_CFG0);
- val |= UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN |
- UTMIP_FORCE_PDZI_POWERDOWN;
- writel(val, base + UTMIP_XCVR_CFG0);
+ val = readl(base + UTMIP_BAT_CHRG_CFG0);
+ val |= UTMIP_PD_CHRG;
+ writel(val, base + UTMIP_BAT_CHRG_CFG0);
val = readl(base + UTMIP_XCVR_CFG1);
val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
UTMIP_FORCE_PDDR_POWERDOWN;
writel(val, base + UTMIP_XCVR_CFG1);
- utmip_pad_power_off(phy);
+ if (phy->instance == 2) {
+ val = readl(base + USB_PORTSC1);
+ val |= USB_PORTSC1_WKCN;
+ writel(val, base + USB_PORTSC1);
+ }
+
+ utmi_phy_clk_disable(phy);
+
+ if (phy->instance == 2) {
+ val = readl(base + USB_SUSP_CTRL);
+ val |= USB_PHY_CLK_VALID_INT_ENB;
+ writel(val, base + USB_SUSP_CTRL);
+ }
+ utmip_pad_power_off(phy, is_dpd);
}
-static void utmi_phy_preresume(struct tegra_usb_phy *phy)
+static void utmi_phy_preresume(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
@@ -708,7 +702,7 @@ static void utmi_phy_preresume(struct tegra_usb_phy *phy)
writel(val, base + UTMIP_TX_CFG0);
}
-static void utmi_phy_postresume(struct tegra_usb_phy *phy)
+static void utmi_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
@@ -718,7 +712,7 @@ static void utmi_phy_postresume(struct tegra_usb_phy *phy)
writel(val, base + UTMIP_TX_CFG0);
}
-static void uhsic_phy_postresume(struct tegra_usb_phy *phy)
+static void uhsic_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
@@ -763,7 +757,7 @@ static void utmi_phy_restore_end(struct tegra_usb_phy *phy)
udelay(10);
}
-static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
+static int ulpi_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
{
int ret;
unsigned long val;
@@ -832,7 +826,7 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
return 0;
}
-static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
+static void ulpi_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
@@ -849,7 +843,7 @@ static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
clk_disable(phy->clk);
}
-static int null_phy_power_on(struct tegra_usb_phy *phy)
+static int null_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
{
const struct tegra_ulpi_trimmer default_trimmer = {0, 0, 4, 4};
unsigned long val;
@@ -943,7 +937,7 @@ static int null_phy_power_on(struct tegra_usb_phy *phy)
return 0;
}
-static void null_phy_power_off(struct tegra_usb_phy *phy)
+static void null_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
@@ -953,7 +947,7 @@ static void null_phy_power_off(struct tegra_usb_phy *phy)
writel(val, base + ULPI_TIMING_CTRL_0);
}
-static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
+static int uhsic_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
@@ -1035,7 +1029,7 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
return 0;
}
-static void uhsic_phy_power_off(struct tegra_usb_phy *phy)
+static void uhsic_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
@@ -1184,6 +1178,10 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
goto err1;
}
}
+ if (((phy->instance == 0) || (phy->instance == 2)) &&
+ (phy->mode == TEGRA_USB_PHY_MODE_HOST)) {
+ vbus_enable(usb_phy_data[phy->instance].vbus_gpio);
+ }
return phy;
@@ -1195,7 +1193,7 @@ err0:
return ERR_PTR(err);
}
-int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
+int tegra_usb_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
{
if (!phy->regulator_on) {
regulator_enable(phy->reg_vdd);
@@ -1204,27 +1202,27 @@ int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
if (phy_is_ulpi(phy)) {
struct tegra_ulpi_config *ulpi_config = phy->config;
if (ulpi_config->inf_type == TEGRA_USB_LINK_ULPI)
- return ulpi_phy_power_on(phy);
+ return ulpi_phy_power_on(phy, is_dpd);
else if (ulpi_config->inf_type == TEGRA_USB_UHSIC)
- return uhsic_phy_power_on(phy);
+ return uhsic_phy_power_on(phy, is_dpd);
else
- return null_phy_power_on(phy);
+ return null_phy_power_on(phy, is_dpd);
} else
- return utmi_phy_power_on(phy);
+ return utmi_phy_power_on(phy, is_dpd);
}
-void tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
+void tegra_usb_phy_power_off(struct tegra_usb_phy *phy, bool is_dpd)
{
if (phy_is_ulpi(phy)) {
struct tegra_ulpi_config *ulpi_config = phy->config;
if (ulpi_config->inf_type == TEGRA_USB_LINK_ULPI)
- ulpi_phy_power_off(phy);
+ ulpi_phy_power_off(phy, is_dpd);
else if (ulpi_config->inf_type == TEGRA_USB_UHSIC)
- uhsic_phy_power_off(phy);
+ uhsic_phy_power_off(phy, is_dpd);
else
- null_phy_power_off(phy);
+ null_phy_power_off(phy, is_dpd);
} else
- utmi_phy_power_off(phy);
+ utmi_phy_power_off(phy, is_dpd);
if (phy->regulator_on && (tegra_get_revision() >= TEGRA_REVISION_A03)) {
regulator_disable(phy->reg_vdd);
@@ -1232,23 +1230,21 @@ void tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
}
}
-void tegra_usb_phy_preresume(struct tegra_usb_phy *phy)
+void tegra_usb_phy_preresume(struct tegra_usb_phy *phy, bool is_dpd)
{
if (!phy_is_ulpi(phy))
- utmi_phy_preresume(phy);
+ utmi_phy_preresume(phy, is_dpd);
}
-void tegra_usb_phy_postresume(struct tegra_usb_phy *phy)
+void tegra_usb_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd)
{
struct tegra_ulpi_config *config = phy->config;
if ((phy->instance == 1) &&
(config->inf_type == TEGRA_USB_UHSIC))
- uhsic_phy_postresume(phy);
+ uhsic_phy_postresume(phy, is_dpd);
else if (!phy_is_ulpi(phy))
- utmi_phy_postresume(phy);
-
- return 0;
+ utmi_phy_postresume(phy, is_dpd);
}
void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
@@ -1285,6 +1281,9 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy)
clk_put(phy->clk);
} else
utmip_pad_close(phy);
+ if (phy->mode == TEGRA_USB_PHY_MODE_HOST) {
+ vbus_disable(usb_phy_data[phy->instance].vbus_gpio);
+ }
clk_disable(phy->pll_u);
clk_put(phy->pll_u);
regulator_put(phy->reg_vdd);
diff --git a/drivers/usb/gadget/fsl_tegra_udc.c b/drivers/usb/gadget/fsl_tegra_udc.c
index 8589ef781039..712636d8ee8e 100644
--- a/drivers/usb/gadget/fsl_tegra_udc.c
+++ b/drivers/usb/gadget/fsl_tegra_udc.c
@@ -80,8 +80,7 @@ int fsl_udc_clk_init(struct platform_device *pdev)
err = PTR_ERR(phy);
goto err1;
}
-
- tegra_usb_phy_power_on(phy);
+ tegra_usb_phy_power_on(phy, true);
return 0;
err1:
@@ -118,18 +117,18 @@ void fsl_udc_clk_release(void)
clk_put(emc_clk);
}
-void fsl_udc_clk_suspend(void)
+void fsl_udc_clk_suspend(bool is_dpd)
{
- tegra_usb_phy_power_off(phy);
+ tegra_usb_phy_power_off(phy, is_dpd);
clk_disable(udc_clk);
clk_disable(sclk_clk);
clk_disable(emc_clk);
}
-void fsl_udc_clk_resume(void)
+void fsl_udc_clk_resume(bool is_dpd)
{
clk_enable(emc_clk);
clk_enable(sclk_clk);
clk_enable(udc_clk);
- tegra_usb_phy_power_on(phy);
+ tegra_usb_phy_power_on(phy, is_dpd);
}
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 74ebe55a1ca0..c67230db46eb 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1216,9 +1216,9 @@ static int fsl_vbus_session(struct usb_gadget *gadget, int is_active)
udc->vbus_active = 0;
udc->usb_state = USB_STATE_DEFAULT;
spin_unlock_irqrestore(&udc->lock, flags);
- fsl_udc_clk_suspend();
+ fsl_udc_clk_suspend(false);
} else if (!udc->vbus_active && is_active) {
- fsl_udc_clk_resume();
+ fsl_udc_clk_resume(false);
/* setup the controller in the device mode */
dr_controller_setup(udc);
/* setup EP0 for setup packet */
@@ -2751,7 +2751,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
if (udc_controller->transceiver) {
dr_controller_stop(udc_controller);
dr_controller_reset(udc_controller);
- fsl_udc_clk_suspend();
+ fsl_udc_clk_suspend(false);
udc_controller->vbus_active = 0;
udc_controller->usb_state = USB_STATE_DEFAULT;
otg_set_peripheral(udc_controller->transceiver, &udc_controller->gadget);
@@ -2760,7 +2760,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
#ifdef CONFIG_ARCH_TEGRA
/* Power down the phy if cable is not connected */
if (!(fsl_readl(&usb_sys_regs->vbus_wakeup) & USB_SYS_VBUS_STATUS))
- fsl_udc_clk_suspend();
+ fsl_udc_clk_suspend(false);
#endif
#endif
@@ -2847,7 +2847,7 @@ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state)
if (udc_controller->transceiver) {
udc_controller->transceiver->state = OTG_STATE_UNDEFINED;
}
- fsl_udc_clk_suspend();
+ fsl_udc_clk_suspend(true);
return 0;
}
@@ -2868,13 +2868,13 @@ static int fsl_udc_resume(struct platform_device *pdev)
/* if there is no VBUS then power down the clocks and return */
return 0;
} else {
- fsl_udc_clk_resume();
+ fsl_udc_clk_resume(true);
/* Detected VBUS set the transceiver state to device mode */
udc_controller->transceiver->state = OTG_STATE_B_PERIPHERAL;
}
} else {
/* enable the clocks to the controller */
- fsl_udc_clk_resume();
+ fsl_udc_clk_resume(true);
}
#if defined(CONFIG_ARCH_TEGRA)
@@ -2891,7 +2891,7 @@ static int fsl_udc_resume(struct platform_device *pdev)
#endif
/* Power down the phy if cable is not connected */
if (!(fsl_readl(&usb_sys_regs->vbus_wakeup) & USB_SYS_VBUS_STATUS))
- fsl_udc_clk_suspend();
+ fsl_udc_clk_suspend(false);
return 0;
}
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
index 99c36054e66c..19d113c03af6 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -587,8 +587,8 @@ struct platform_device;
int fsl_udc_clk_init(struct platform_device *pdev);
void fsl_udc_clk_finalize(struct platform_device *pdev);
void fsl_udc_clk_release(void);
-void fsl_udc_clk_suspend(void);
-void fsl_udc_clk_resume(void);
+void fsl_udc_clk_suspend(bool is_dpd);
+void fsl_udc_clk_resume(bool is_dpd);
#else
static inline int fsl_udc_clk_init(struct platform_device *pdev)
{
@@ -600,10 +600,10 @@ static inline void fsl_udc_clk_finalize(struct platform_device *pdev)
static inline void fsl_udc_clk_release(void)
{
}
-static inline void fsl_udc_clk_suspend(void)
+static inline void fsl_udc_clk_suspend(bool is_dpd)
{
}
-static inline void fsl_udc_clk_resume(void)
+static inline void fsl_udc_clk_resume(bool is_dpd)
{
}
#endif
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index fab9edb4cc99..3a28122b451a 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -30,6 +30,10 @@
#define TEGRA_USB_SUSP_CLR (1 << 5)
#define TEGRA_USB_PHY_CLK_VALID (1 << 7)
#define TEGRA_USB_SRT (1 << 25)
+#define TEGRA_USB_PHY_CLK_VALID_INT_ENB (1 << 9)
+
+#define TEGRA_USB_PORTSC1_OFFSET 0x184
+#define TEGRA_USB_PORTSC1_WKCN (1 << 20)
#define TEGRA_LVL2_CLK_GATE_OVRB 0xfc
#define TEGRA_USB2_CLK_OVR_ON (1 << 10)
@@ -53,26 +57,43 @@ struct tegra_ehci_hcd {
enum tegra_usb_phy_port_speed port_speed;
};
-static void tegra_ehci_power_up(struct usb_hcd *hcd)
+static void tegra_ehci_power_up(struct usb_hcd *hcd, bool is_dpd)
{
struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
clk_enable(tegra->emc_clk);
clk_enable(tegra->sclk_clk);
- clk_enable(tegra->clk);
- tegra_usb_phy_power_on(tegra->phy);
+ tegra_usb_phy_power_on(tegra->phy, is_dpd);
tegra->host_resumed = 1;
}
-static void tegra_ehci_power_down(struct usb_hcd *hcd)
+static void tegra_ehci_power_down(struct usb_hcd *hcd, bool is_dpd)
{
struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
tegra->host_resumed = 0;
- tegra_usb_phy_power_off(tegra->phy);
- clk_disable(tegra->clk);
- clk_disable(tegra->sclk_clk);
+ tegra_usb_phy_power_off(tegra->phy, is_dpd);
clk_disable(tegra->emc_clk);
+ clk_disable(tegra->sclk_clk);
+}
+
+static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+ u32 val;
+
+ spin_lock (&ehci->lock);
+ val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET);
+ val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB;
+ writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET));
+
+ val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET);
+ val &= ~TEGRA_USB_PORTSC1_WKCN;
+ writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET));
+
+ spin_unlock (&ehci->lock);
+
+ return ehci_irq(hcd);
}
static int tegra_ehci_hub_control(
@@ -94,7 +115,11 @@ static int tegra_ehci_hub_control(
unsigned selector;
struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
bool hsic = false;
-
+ if (!tegra->host_resumed) {
+ if (buf)
+ memset (buf, 0, wLength);
+ return retval;
+ }
if (tegra->phy->instance == 1) {
struct tegra_ulpi_config *config = tegra->phy->config;
hsic = (config->inf_type == TEGRA_USB_UHSIC);
@@ -118,7 +143,7 @@ static int tegra_ehci_hub_control(
if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
/* Resume completed, re-enable disconnect detection */
tegra->port_resuming = 0;
- tegra_usb_phy_postresume(tegra->phy);
+ tegra_usb_phy_postresume(tegra->phy, false);
}
} else if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
temp = ehci_readl(ehci, status_reg);
@@ -164,7 +189,7 @@ static int tegra_ehci_hub_control(
goto done;
/* Disable disconnect detection during port resume */
- tegra_usb_phy_preresume(tegra->phy);
+ tegra_usb_phy_preresume(tegra->phy, false);
ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25);
@@ -308,7 +333,7 @@ static void tegra_ehci_restart(struct usb_hcd *hcd)
ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
}
-static int tegra_usb_suspend(struct usb_hcd *hcd)
+static int tegra_usb_suspend(struct usb_hcd *hcd, bool is_dpd)
{
struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
struct ehci_regs __iomem *hw = tegra->ehci->regs;
@@ -325,15 +350,14 @@ static int tegra_usb_suspend(struct usb_hcd *hcd)
tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3;
ehci_halt(tegra->ehci);
- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
spin_unlock_irqrestore(&tegra->ehci->lock, flags);
- tegra_ehci_power_down(hcd);
+ tegra_ehci_power_down(hcd, is_dpd);
return 0;
}
-static int tegra_usb_resume(struct usb_hcd *hcd)
+static int tegra_usb_resume(struct usb_hcd *hcd, bool is_dpd)
{
struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
struct usb_device *udev = hcd->self.root_hub;
@@ -349,7 +373,7 @@ static int tegra_usb_resume(struct usb_hcd *hcd)
}
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- tegra_ehci_power_up(hcd);
+ tegra_ehci_power_up(hcd, is_dpd);
if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) {
/* Wait for the phy to detect new devices
@@ -457,12 +481,12 @@ static void tegra_ehci_shutdown(struct usb_hcd *hcd)
/* ehci_shutdown touches the USB controller registers, make sure
* controller has clocks to it */
if (!tegra->host_resumed)
- tegra_ehci_power_up(hcd);
+ tegra_ehci_power_up(hcd, false);
ehci_shutdown(hcd);
/* we are ready to shut down, powerdown the phy */
- tegra_ehci_power_down(hcd);
+ tegra_ehci_power_down(hcd, false);
}
static int tegra_ehci_setup(struct usb_hcd *hcd)
@@ -508,7 +532,7 @@ static int tegra_ehci_bus_suspend(struct usb_hcd *hcd)
error_status = ehci_bus_suspend(hcd);
if (!error_status && tegra->power_down_on_bus_suspend) {
- tegra_usb_suspend(hcd);
+ tegra_usb_suspend(hcd, false);
tegra->bus_suspended = 1;
}
return error_status;
@@ -519,11 +543,11 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd)
struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
if (tegra->bus_suspended && tegra->power_down_on_bus_suspend) {
- tegra_usb_resume(hcd);
+ tegra_usb_resume(hcd, false);
tegra->bus_suspended = 0;
}
- tegra_usb_phy_preresume(tegra->phy);
+ tegra_usb_phy_preresume(tegra->phy, false);
tegra->port_resuming = 1;
return ehci_bus_resume(hcd);
}
@@ -775,7 +799,7 @@ static const struct hc_driver tegra_ehci_hc_driver = {
.flags = HCD_USB2 | HCD_MEMORY,
.reset = tegra_ehci_setup,
- .irq = ehci_irq,
+ .irq = tegra_ehci_irq,
.start = ehci_run,
.stop = ehci_stop,
@@ -885,7 +909,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
goto fail_phy;
}
- err = tegra_usb_phy_power_on(tegra->phy);
+ err = tegra_usb_phy_power_on(tegra->phy, true);
if (err) {
dev_err(&pdev->dev, "Failed to power on the phy\n");
goto fail;
@@ -966,7 +990,7 @@ static int tegra_ehci_resume(struct platform_device *pdev)
if ((tegra->bus_suspended) && (tegra->power_down_on_bus_suspend))
return 0;
- return tegra_usb_resume(hcd);
+ return tegra_usb_resume(hcd, true);
}
static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state)
@@ -980,7 +1004,7 @@ static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state)
if (time_before(jiffies, tegra->ehci->next_statechange))
msleep(10);
- return tegra_usb_suspend(hcd);
+ return tegra_usb_suspend(hcd, true);
}
#endif
@@ -1012,7 +1036,7 @@ static int tegra_ehci_remove(struct platform_device *pdev)
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
cancel_delayed_work(&tegra->work);
- tegra_usb_phy_power_off(tegra->phy);
+ tegra_usb_phy_power_off(tegra->phy, true);
tegra_usb_phy_close(tegra->phy);
iounmap(hcd->regs);
diff --git a/drivers/usb/otg/tegra-otg.c b/drivers/usb/otg/tegra-otg.c
index 386bb8b922da..893b897f5957 100644
--- a/drivers/usb/otg/tegra-otg.c
+++ b/drivers/usb/otg/tegra-otg.c
@@ -342,7 +342,6 @@ static int tegra_otg_probe(struct platform_device *pdev)
INIT_WORK (&tegra->work, irq_work);
dev_info(&pdev->dev, "otg transceiver registered\n");
- clk_disable(tegra->clk);
return 0;
err_irq: