]> Pileus Git - ~andy/linux/blobdiff - drivers/usb/host/ehci-hcd.c
Merge branch 'nfsd-next' of git://linux-nfs.org/~bfields/linux
[~andy/linux] / drivers / usb / host / ehci-hcd.c
index e8ba4c44223a5c360ec552cbbb4137ca2b4ca3b2..81cda09b47e3127772e51cbc5c57eab7761c4a52 100644 (file)
@@ -71,7 +71,6 @@
 static const char      hcd_name [] = "ehci_hcd";
 
 
-#undef VERBOSE_DEBUG
 #undef EHCI_URB_TRACE
 
 /* magic numbers that can affect system performance */
@@ -686,8 +685,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     status, masked_status, pcd_status = 0, cmd;
        int                     bh;
+       unsigned long           flags;
 
-       spin_lock (&ehci->lock);
+       /*
+        * For threadirqs option we use spin_lock_irqsave() variant to prevent
+        * deadlock with ehci hrtimer callback, because hrtimer callbacks run
+        * in interrupt context even when threadirqs is specified. We can go
+        * back to spin_lock() variant when hrtimer callbacks become threaded.
+        */
+       spin_lock_irqsave(&ehci->lock, flags);
 
        status = ehci_readl(ehci, &ehci->regs->status);
 
@@ -705,7 +711,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
        /* Shared IRQ? */
        if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
-               spin_unlock(&ehci->lock);
+               spin_unlock_irqrestore(&ehci->lock, flags);
                return IRQ_NONE;
        }
 
@@ -714,13 +720,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
        cmd = ehci_readl(ehci, &ehci->regs->command);
        bh = 0;
 
-#ifdef VERBOSE_DEBUG
-       /* unrequested/ignored: Frame List Rollover */
-       dbg_status (ehci, "irq", status);
-#endif
-
-       /* INT, ERR, and IAA interrupt rates can be throttled */
-
        /* normal [4.15.1.2] or error [4.15.1.1] completion */
        if (likely ((status & (STS_INT|STS_ERR)) != 0)) {
                if (likely ((status & STS_ERR) == 0))
@@ -823,7 +822,7 @@ dead:
 
        if (bh)
                ehci_work (ehci);
-       spin_unlock (&ehci->lock);
+       spin_unlock_irqrestore(&ehci->lock, flags);
        if (pcd_status)
                usb_hcd_poll_rh_status(hcd);
        return IRQ_HANDLED;
@@ -1320,7 +1319,7 @@ static int __init ehci_hcd_init(void)
                 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
                 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
 
-#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+#ifdef CONFIG_DYNAMIC_DEBUG
        ehci_debug_root = debugfs_create_dir("ehci", usb_debug_root);
        if (!ehci_debug_root) {
                retval = -ENOENT;
@@ -1369,7 +1368,7 @@ clean2:
        platform_driver_unregister(&PLATFORM_DRIVER);
 clean0:
 #endif
-#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+#ifdef CONFIG_DYNAMIC_DEBUG
        debugfs_remove(ehci_debug_root);
        ehci_debug_root = NULL;
 err_debug:
@@ -1393,7 +1392,7 @@ static void __exit ehci_hcd_cleanup(void)
 #ifdef PS3_SYSTEM_BUS_DRIVER
        ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
 #endif
-#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+#ifdef CONFIG_DYNAMIC_DEBUG
        debugfs_remove(ehci_debug_root);
 #endif
        clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);