Please merge.

- Dave
Various tweaks to EHCI IRQ handling, these may affact some systems.

 - Delays enabling IRQs until the root hub is more fully set up, so
   any "resume detect" IRQs can be handled properly.  (Craig Nadler)

 - Power down ports on driver shutdown.  (Craig Nadler)

 - Remove some duplicate irq-sharing logic that somehow crept in; check
   only once, and return IRQ_NONE to detect IRQ storms better (db)

 - Minor comment fix re integrated TTs.  (db)

From:           Craig Nadler <[EMAIL PROTECTED]>
Signed-off-by:  David Brownell <[EMAIL PROTECTED]>


--- a/drivers/usb/host/ehci-hcd.c       Mon Jun 21 13:19:18 2004
+++ b/drivers/usb/host/ehci-hcd.c       Mon Jun 21 13:19:18 2004
@@ -425,7 +425,6 @@
                ehci_mem_cleanup (ehci);
                return retval;
        }
-       writel (INTR_MASK, &ehci->regs->intr_enable);
        writel (ehci->periodic_dma, &ehci->regs->frame_list);
 
 #ifdef CONFIG_PCI
@@ -531,7 +530,8 @@
        /*
         * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
         * are explicitly handed to companion controller(s), so no TT is
-        * involved with the root hub.
+        * involved with the root hub.  (Except where one is integrated,
+        * and there's no companion controller unless maybe for USB OTG.)
         */
        ehci->reboot_notifier.notifier_call = ehci_reboot;
        register_reboot_notifier (&ehci->reboot_notifier);
@@ -563,6 +563,8 @@
                goto done2;
        }
 
+       writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */
+
        create_debug_files (ehci);
 
        return 0;
@@ -573,6 +575,7 @@
 static void ehci_stop (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
+       u8                      rh_ports, port;
 
        ehci_dbg (ehci, "stop\n");
 
@@ -584,7 +587,16 @@
                return;
        }
        del_timer_sync (&ehci->watchdog);
+
+       /* Turn off port power on all root hub ports. */
+       rh_ports = HCS_N_PORTS (ehci->hcs_params);
+       for (port = 1; port <= rh_ports; port++) {
+               ehci_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER,
+                       port, NULL, 0);
+       }
+
        ehci_reset (ehci);
+       writel (0, &ehci->regs->intr_enable);
 
        /* let companion controllers work when we aren't */
        writel (0, &ehci->regs->configured_flag);
@@ -704,12 +716,6 @@
 
        status = readl (&ehci->regs->status);
 
-       /* shared irq */
-       if (status == 0) {
-               spin_unlock (&ehci->lock);
-               return IRQ_NONE;
-       }
-
        /* e.g. cardbus physical eject */
        if (status == ~(u32) 0) {
                ehci_dbg (ehci, "device removed\n");
@@ -717,8 +723,10 @@
        }
 
        status &= INTR_MASK;
-       if (!status)                    /* irq sharing? */
-               goto done;
+       if (!status) {                  /* irq sharing? */
+               spin_unlock(&ehci->lock);
+               return IRQ_NONE;
+       }
 
        /* clear (just) interrupts */
        writel (status, &ehci->regs->status);
@@ -789,7 +797,6 @@
 
        if (bh)
                ehci_work (ehci, regs);
-done:
        spin_unlock (&ehci->lock);
        return IRQ_HANDLED;
 }

Reply via email to