summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2011-06-27 16:53:12 +0900
committerRohan Somvanshi <rsomvanshi@nvidia.com>2011-06-29 03:43:23 -0700
commitd7b102eca117b41c0f244b292d076e574608c565 (patch)
tree27d434b03b9d64cea18a417715b1f9789258320c
parent4a4cae3323d3287e77fdc504e38656974ef24848 (diff)
tegra: usb: prevent crash if irq occurs while sleeping
In some rare cases, EHCI irqs interrupts be triggered while the block is suspended. This is notably the case when unplugging a host cable to which no device is attached. In this case, the interrupt handler will be called with the block powered off, which will eventually crash. This patch workarounds this by returning from the interrupt handler immediatly if the block is not powered on. Change-Id: I7763f56f20a984e3db716306b6bf8ec223c90363 Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-on: http://git-master/r/35604 Reviewed-by: Suresh Mangipudi <smangipudi@nvidia.com> Reviewed-by: Hanumanth Venkateswa Moganty <vmoganty@nvidia.com>
-rw-r--r--drivers/usb/host/ehci-tegra.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 8ae3172af678..90c88009ed45 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -81,6 +81,7 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd, bool is_dpd)
static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+ struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
struct ehci_regs __iomem *hw = ehci->regs;
u32 val;
@@ -97,9 +98,14 @@ static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd)
val = readl(&hw->status);
if (!(val & STS_PCD)) {
spin_unlock (&ehci->lock);
- return 0;
+ return IRQ_NONE;
}
}
+ /* we would lock if we went further without power */
+ if (!tegra->host_resumed) {
+ spin_unlock (&ehci->lock);
+ return IRQ_HANDLED;
+ }
spin_unlock (&ehci->lock);
return ehci_irq(hcd);
}