ChangeSet 1.2181.4.95, 2005/03/29 23:43:56-08:00, [EMAIL PROTECTED]

        [PATCH] USB: ohci D3 resume fix
        
        This fixes a problem that cropped up resuming OHCI from PCI D3 on
        NForce2.  Evidently the register controlling frame timing gets
        clobbered in D3, but not other registers ... a "by the book" reinit
        seems to solve this particular problem.  (And ought to help a few
        startup glitches on other implementations.  Linux never used that
        toggle bit before, and has had to struggle with glitchy init...)
        
        It also updates some diagnostics to be bit more useful, and tries
        to avoid a particular "wakeup while suspending" glitch that seems
        particular to one particular type of Australian mouse.
        
        Signed-off-by: David Brownell <[EMAIL PROTECTED]>
        Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>



 ohci-dbg.c |    6 ++++++
 ohci-hcd.c |    4 ++--
 ohci-hub.c |    5 +++--
 ohci.h     |    8 ++++++--
 4 files changed, 17 insertions(+), 6 deletions(-)


diff -Nru a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
--- a/drivers/usb/host/ohci-dbg.c       2005-03-30 15:24:30 -08:00
+++ b/drivers/usb/host/ohci-dbg.c       2005-03-30 15:24:30 -08:00
@@ -193,6 +193,10 @@
 
        maybe_print_eds (controller, "donehead",
                        ohci_readl (controller, &regs->donehead), next, size);
+
+       /* broken fminterval means traffic won't flow! */ 
+       ohci_dbg (controller, "fminterval %08x\n", 
+                       ohci_readl (controller, &regs->fminterval));
 }
 
 #define dbg_port_sw(hc,num,value,next,size) \
@@ -620,9 +624,11 @@
 
        ohci_dbg_sw (ohci, &next, &size,
                "bus %s, device %s\n"
+               "%s\n"
                "%s version " DRIVER_VERSION "\n",
                hcd->self.controller->bus->name,
                hcd->self.controller->bus_id,
+               hcd->product_desc,
                hcd_name);
 
        if (bus->controller->power.power_state) {
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c       2005-03-30 15:24:30 -08:00
+++ b/drivers/usb/host/ohci-hcd.c       2005-03-30 15:24:30 -08:00
@@ -587,7 +587,6 @@
                // flush those writes
                (void) ohci_readl (ohci, &ohci->regs->control);
        }
-       ohci_writel (ohci, ohci->fminterval, &ohci->regs->fminterval);
 
        /* Tell the controller where the control and bulk lists are
         * The lists are empty now. */
@@ -728,7 +727,8 @@
 
        if (ints & OHCI_INTR_RD) {
                ohci_vdbg (ohci, "resume detect\n");
-               schedule_work(&ohci->rh_resume);
+               if (hcd->state != HC_STATE_QUIESCING)
+                       schedule_work(&ohci->rh_resume);
        }
 
        if (ints & OHCI_INTR_WDH) {
diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
--- a/drivers/usb/host/ohci-hub.c       2005-03-30 15:24:30 -08:00
+++ b/drivers/usb/host/ohci-hub.c       2005-03-30 15:24:30 -08:00
@@ -169,7 +169,7 @@
                ohci_info (ohci, "wakeup\n");
                break;
        case OHCI_USB_OPER:
-               ohci_dbg (ohci, "odd resume\n");
+               ohci_dbg (ohci, "already resumed\n");
                status = 0;
                break;
        default:                /* RESET, we lost power */
@@ -197,7 +197,7 @@
                                &ohci->regs->roothub.portstatus [temp]);
        }
 
-       /* Some controllers (lucent) need extra-long delays */
+       /* Some controllers (lucent erratum) need extra-long delays */
        hcd->state = HC_STATE_RESUMING;
        mdelay (20 /* usb 11.5.1.10 */ + 15);
 
@@ -216,6 +216,7 @@
        ohci_writel (ohci, 0, &ohci->regs->ed_periodcurrent);
        ohci_writel (ohci, (u32) ohci->hcca_dma, &ohci->regs->hcca);
 
+       /* Sometimes PCI D3 suspend trashes frame timings ... */
        periodic_reinit (ohci);
 
        /* interrupts might have been disabled */
diff -Nru a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
--- a/drivers/usb/host/ohci.h   2005-03-30 15:24:30 -08:00
+++ b/drivers/usb/host/ohci.h   2005-03-30 15:24:30 -08:00
@@ -599,12 +599,16 @@
 
 #define        FI                      0x2edf          /* 12000 bits per frame 
(-1) */
 #define        FSMP(fi)                (0x7fff & ((6 * ((fi) - 210)) / 7))
+#define        FIT                     (1 << 31)
 #define LSTHRESH               0x628           /* lowspeed bit threshold */
 
-static inline void periodic_reinit (struct ohci_hcd *ohci)
+static void periodic_reinit (struct ohci_hcd *ohci)
 {
-       u32     fi = ohci->fminterval & 0x0ffff;
+       u32     fi = ohci->fminterval & 0x03fff;
+       u32     fit = ohci_readl(ohci, &ohci->regs->fminterval) & FIT;
 
+       ohci_writel (ohci, (fit ^ FIT) | ohci->fminterval,
+                                               &ohci->regs->fminterval);
        ohci_writel (ohci, ((9 * fi) / 10) & 0x3fff,
                                                &ohci->regs->periodicstart);
 }
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to