diff options
author | Venkat Moganty <vmoganty@nvidia.com> | 2010-10-20 12:04:49 +0530 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2010-10-21 15:35:15 -0700 |
commit | cb800e32170138f00aad5b724dc56c18ce1b07ad (patch) | |
tree | 690eb3fc3058a94e5eb7b1943e8d3ce68a5ebad9 | |
parent | a01b22145d0cb8fe4092fae4ab3595ab3470502f (diff) |
[ehci-tegra] Fix VBUS handling in OTG mode
When USB cable is removed from the USB1 port side then VBUS is turned
off but, if USB cable is removed from the device side then VBUS is not
getting turned off and is showing high even when USB cable is removed
completely from the USB1 port. Fixed this by checking the OTG state
"OTG_STATE_A_SUSPEND" and then turning off the VBUS and phy power down.
Bug 741587
Change-Id: Ib8f3dbddc48de0d12179dbd504503621854f44cd
Reviewed-on: http://git-master/r/8199
Reviewed-by: Lance Zhao <lazhao@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Tested-by: Lance Zhao <lazhao@nvidia.com>
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rw-r--r-- | drivers/usb/host/ehci-tegra.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 1d24a03cd903..926fb5882c0d 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -236,6 +236,15 @@ static void tegra_ehci_irq_work(struct work_struct* irq_work) kick_rhub = true; tegra_ehci_restart(hcd); } + } else if (ehci->transceiver->state == OTG_STATE_A_SUSPEND) { + if (ehci->host_reinited) { + /* indicate hcd flags, that hardware is not accessible now */ + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + ehci_halt(ehci); + tegra_ehci_power_down(hcd); + ehci->transceiver->state = OTG_STATE_UNDEFINED; + ehci->host_reinited = 0; + } } } else #endif @@ -284,6 +293,10 @@ static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) if (!ehci->host_reinited) { spin_unlock (&ehci->lock); return IRQ_HANDLED; + } else { + schedule_work(&ehci->irq_work); + spin_unlock (&ehci->lock); + return IRQ_HANDLED; } } else { spin_unlock (&ehci->lock); |