Commit e3fc695b authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: net2280 updates

Net2280 patches to:

  - Make reset logic ensure endpoint toggle and halt bits only get cleared
    on endpoints other than ep0 to fix an extremely unlikely (but possible)
    state when a setup packet come in after we've checked the reset status
    but before calling ep_reset().

  - Avoid a disconnect hang by exchanging SUSPEND_IMMEDIATELY (intended for
    use when the 8051 is the PCI host) with SUSPEND_REQUEST_INTERRUPT to
    suspend the NET2280.

  - Make rmmod of gadget drivers trigger disconnect; earlier changes to
    reset logic broke this.
Signed-off-by: default avatarAlex Sanks <alex@netchip.com>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent b41cb145
......@@ -303,13 +303,16 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep)
/* init to our chosen defaults, notably so that we NAK OUT
* packets until the driver queues a read (+note erratum 0112)
*/
writel ( (1 << SET_NAK_OUT_PACKETS_MODE)
tmp = (1 << SET_NAK_OUT_PACKETS_MODE)
| (1 << SET_NAK_OUT_PACKETS)
| (1 << CLEAR_EP_HIDE_STATUS_PHASE)
| (1 << CLEAR_INTERRUPT_MODE)
| (1 << CLEAR_ENDPOINT_TOGGLE)
| (1 << CLEAR_ENDPOINT_HALT)
, &ep->regs->ep_rsp);
| (1 << CLEAR_INTERRUPT_MODE);
if (ep->num != 0) {
tmp |= (1 << CLEAR_ENDPOINT_TOGGLE)
| (1 << CLEAR_ENDPOINT_HALT);
}
writel (tmp, &ep->regs->ep_rsp);
/* scrub most status bits, and flush any fifo state */
writel ( (1 << TIMEOUT)
......@@ -1920,8 +1923,6 @@ static void ep0_start (struct net2280 *dev)
, &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)
| (dev->softconnect << USB_DETECT_ENABLE)
| (1 << SELF_POWERED_STATUS)
......@@ -2047,6 +2048,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
stop_activity (dev, driver);
spin_unlock_irqrestore (&dev->lock, flags);
net2280_pullup (&dev->gadget, 0);
driver->unbind (&dev->gadget);
dev->gadget.dev.driver = NULL;
dev->driver = NULL;
......@@ -2552,8 +2555,6 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment