ChangeSet 1.1722.97.53, 2004/06/08 16:08:52-07:00, david-b@pacbell.net [PATCH] USB: usb suspend/resume work better on net2280 This makes net2280 behave more correctly with respect to usb suspend and resume processing. So for example gadget zero autoresume testing works. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/gadget/net2280.c | 25 +++++++++++++++++-------- 1 files changed, 17 insertions(+), 8 deletions(-) diff -Nru a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c --- a/drivers/usb/gadget/net2280.c Fri Jun 18 10:58:48 2004 +++ b/drivers/usb/gadget/net2280.c Fri Jun 18 10:58:48 2004 @@ -1902,6 +1902,8 @@ , &dev->usb->stdrsp); writel ( (1 << USB_ROOT_PORT_WAKEUP_ENABLE) | (1 << SELF_POWERED_USB_DEVICE) + /* erratum 0102 workaround */ + | ((dev->chiprev == 0100) ? 0 : 1) << SUSPEND_IMMEDIATELY | (1 << REMOTE_WAKEUP_SUPPORT) | (1 << USB_DETECT_ENABLE) | (1 << SELF_POWERED_STATUS) @@ -1917,6 +1919,7 @@ | (1 << PCI_RETRY_ABORT_INTERRUPT_ENABLE) | (1 << VBUS_INTERRUPT_ENABLE) | (1 << ROOT_PORT_RESET_INTERRUPT_ENABLE) + | (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) , &dev->regs->pciirqenb1); /* don't leave any writes posted */ @@ -2513,19 +2516,24 @@ return; } - /* NOTE: we don't actually suspend the hardware; that starts to - * interact with PCI power management, and needs something like a - * controller->suspend() call to clear SUSPEND_REQUEST_INTERRUPT. - * we shouldn't see resume interrupts. - * for rev 0100, this also avoids erratum 0102. + /* NOTE: chip stays in PCI D0 state for now, but it could + * enter D1 to save more power */ tmp = (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT); if (stat & tmp) { - if (dev->driver->suspend) - dev->driver->suspend (&dev->gadget); + writel (tmp, &dev->regs->irqstat1); + if (stat & (1 << SUSPEND_REQUEST_INTERRUPT)) { + if (dev->driver->suspend) + dev->driver->suspend (&dev->gadget); + /* we use SUSPEND_IMMEDIATELY */ + stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT); + } else { + if (dev->driver->resume) + dev->driver->resume (&dev->gadget); + /* at high speed, note erratum 0133 */ + } stat &= ~tmp; } - stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT); /* clear any other status/irqs */ if (stat) @@ -2533,6 +2541,7 @@ /* some status we can just ignore */ stat &= ~((1 << CONTROL_STATUS_INTERRUPT) + | (1 << SUSPEND_REQUEST_INTERRUPT) | (1 << RESUME_INTERRUPT) | (1 << SOF_INTERRUPT)); if (!stat)