diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2011-06-27 16:53:12 +0900 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2011-06-29 03:43:23 -0700 |
commit | d7b102eca117b41c0f244b292d076e574608c565 (patch) | |
tree | 27d434b03b9d64cea18a417715b1f9789258320c | |
parent | 4a4cae3323d3287e77fdc504e38656974ef24848 (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.c | 8 |
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); } |