diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/hcd.c | 16 | ||||
-rw-r--r-- | drivers/usb/host/ehci-ls1x.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ohci-xls.c | 2 |
3 files changed, 18 insertions, 2 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1e741bca0265..f034716190ff 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); | |||
2151 | irqreturn_t usb_hcd_irq (int irq, void *__hcd) | 2151 | irqreturn_t usb_hcd_irq (int irq, void *__hcd) |
2152 | { | 2152 | { |
2153 | struct usb_hcd *hcd = __hcd; | 2153 | struct usb_hcd *hcd = __hcd; |
2154 | unsigned long flags; | ||
2154 | irqreturn_t rc; | 2155 | irqreturn_t rc; |
2155 | 2156 | ||
2157 | /* IRQF_DISABLED doesn't work correctly with shared IRQs | ||
2158 | * when the first handler doesn't use it. So let's just | ||
2159 | * assume it's never used. | ||
2160 | */ | ||
2161 | local_irq_save(flags); | ||
2162 | |||
2156 | if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) | 2163 | if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) |
2157 | rc = IRQ_NONE; | 2164 | rc = IRQ_NONE; |
2158 | else if (hcd->driver->irq(hcd) == IRQ_NONE) | 2165 | else if (hcd->driver->irq(hcd) == IRQ_NONE) |
@@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) | |||
2160 | else | 2167 | else |
2161 | rc = IRQ_HANDLED; | 2168 | rc = IRQ_HANDLED; |
2162 | 2169 | ||
2170 | local_irq_restore(flags); | ||
2163 | return rc; | 2171 | return rc; |
2164 | } | 2172 | } |
2165 | EXPORT_SYMBOL_GPL(usb_hcd_irq); | 2173 | EXPORT_SYMBOL_GPL(usb_hcd_irq); |
@@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, | |||
2347 | int retval; | 2355 | int retval; |
2348 | 2356 | ||
2349 | if (hcd->driver->irq) { | 2357 | if (hcd->driver->irq) { |
2358 | |||
2359 | /* IRQF_DISABLED doesn't work as advertised when used together | ||
2360 | * with IRQF_SHARED. As usb_hcd_irq() will always disable | ||
2361 | * interrupts we can remove it here. | ||
2362 | */ | ||
2363 | if (irqflags & IRQF_SHARED) | ||
2364 | irqflags &= ~IRQF_DISABLED; | ||
2365 | |||
2350 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", | 2366 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", |
2351 | hcd->driver->description, hcd->self.busnum); | 2367 | hcd->driver->description, hcd->self.busnum); |
2352 | retval = request_irq(irqnum, &usb_hcd_irq, irqflags, | 2368 | retval = request_irq(irqnum, &usb_hcd_irq, irqflags, |
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c index ca759652626b..aa0f328922df 100644 --- a/drivers/usb/host/ehci-ls1x.c +++ b/drivers/usb/host/ehci-ls1x.c | |||
@@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev) | |||
113 | goto err_put_hcd; | 113 | goto err_put_hcd; |
114 | } | 114 | } |
115 | 115 | ||
116 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); | 116 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
117 | if (ret) | 117 | if (ret) |
118 | goto err_put_hcd; | 118 | goto err_put_hcd; |
119 | 119 | ||
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c index 84201cd1a472..41e378f17c66 100644 --- a/drivers/usb/host/ohci-xls.c +++ b/drivers/usb/host/ohci-xls.c | |||
@@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver, | |||
56 | goto err3; | 56 | goto err3; |
57 | } | 57 | } |
58 | 58 | ||
59 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | 59 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
60 | if (retval != 0) | 60 | if (retval != 0) |
61 | goto err4; | 61 | goto err4; |
62 | return retval; | 62 | return retval; |