Commit e592c5d0 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Revert "USB/host: Cleanup unneccessary irq disable code"

This reverts commit 73d40660.

Martin Steigerwald reported that this change caused a hard lockup when
using USB if threadirqs are enabled.  Thomas pointed out that this patch
is incorrect, and can cause problems.  So revert it to get the
previously working functionality back.
Reported-by: default avatarMartin Steigerwald <Martin@lichtvoll.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Chuansheng Liu <chuansheng.liu@intel.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c0bc3098
...@@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); ...@@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum);
irqreturn_t usb_hcd_irq (int irq, void *__hcd) irqreturn_t usb_hcd_irq (int irq, void *__hcd)
{ {
struct usb_hcd *hcd = __hcd; struct usb_hcd *hcd = __hcd;
unsigned long flags;
irqreturn_t rc; irqreturn_t rc;
/* IRQF_DISABLED doesn't work correctly with shared IRQs
* when the first handler doesn't use it. So let's just
* assume it's never used.
*/
local_irq_save(flags);
if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))
rc = IRQ_NONE; rc = IRQ_NONE;
else if (hcd->driver->irq(hcd) == IRQ_NONE) else if (hcd->driver->irq(hcd) == IRQ_NONE)
...@@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) ...@@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
else else
rc = IRQ_HANDLED; rc = IRQ_HANDLED;
local_irq_restore(flags);
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(usb_hcd_irq); EXPORT_SYMBOL_GPL(usb_hcd_irq);
...@@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, ...@@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd,
int retval; int retval;
if (hcd->driver->irq) { if (hcd->driver->irq) {
/* IRQF_DISABLED doesn't work as advertised when used together
* with IRQF_SHARED. As usb_hcd_irq() will always disable
* interrupts we can remove it here.
*/
if (irqflags & IRQF_SHARED)
irqflags &= ~IRQF_DISABLED;
snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
hcd->driver->description, hcd->self.busnum); hcd->driver->description, hcd->self.busnum);
retval = request_irq(irqnum, &usb_hcd_irq, irqflags, retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
......
...@@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev) ...@@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev)
goto err_put_hcd; goto err_put_hcd;
} }
ret = usb_add_hcd(hcd, irq, IRQF_SHARED); ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
if (ret) if (ret)
goto err_put_hcd; goto err_put_hcd;
......
...@@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver, ...@@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver,
goto err3; goto err3;
} }
retval = usb_add_hcd(hcd, irq, IRQF_SHARED); retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
if (retval != 0) if (retval != 0)
goto err4; goto err4;
return retval; return retval;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment