|
@@ -1545,11 +1545,14 @@ static int net2280_pullup(struct usb_gadget *_gadget, int is_on)
|
|
|
writel(tmp | BIT(USB_DETECT_ENABLE), &dev->usb->usbctl);
|
|
|
} else {
|
|
|
writel(tmp & ~BIT(USB_DETECT_ENABLE), &dev->usb->usbctl);
|
|
|
- stop_activity(dev, dev->driver);
|
|
|
+ stop_activity(dev, NULL);
|
|
|
}
|
|
|
|
|
|
spin_unlock_irqrestore(&dev->lock, flags);
|
|
|
|
|
|
+ if (!is_on && dev->driver)
|
|
|
+ dev->driver->disconnect(&dev->gadget);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2466,8 +2469,11 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
|
|
|
nuke(&dev->ep[i]);
|
|
|
|
|
|
/* report disconnect; the driver is already quiesced */
|
|
|
- if (driver)
|
|
|
+ if (driver) {
|
|
|
+ spin_unlock(&dev->lock);
|
|
|
driver->disconnect(&dev->gadget);
|
|
|
+ spin_lock(&dev->lock);
|
|
|
+ }
|
|
|
|
|
|
usb_reinit(dev);
|
|
|
}
|
|
@@ -3341,6 +3347,8 @@ next_endpoints:
|
|
|
BIT(PCI_RETRY_ABORT_INTERRUPT))
|
|
|
|
|
|
static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
|
|
|
+__releases(dev->lock)
|
|
|
+__acquires(dev->lock)
|
|
|
{
|
|
|
struct net2280_ep *ep;
|
|
|
u32 tmp, num, mask, scratch;
|
|
@@ -3381,12 +3389,14 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
|
|
|
if (disconnect || reset) {
|
|
|
stop_activity(dev, dev->driver);
|
|
|
ep0_start(dev);
|
|
|
+ spin_unlock(&dev->lock);
|
|
|
if (reset)
|
|
|
usb_gadget_udc_reset
|
|
|
(&dev->gadget, dev->driver);
|
|
|
else
|
|
|
(dev->driver->disconnect)
|
|
|
(&dev->gadget);
|
|
|
+ spin_lock(&dev->lock);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
@@ -3405,6 +3415,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
|
|
|
tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT);
|
|
|
if (stat & tmp) {
|
|
|
writel(tmp, &dev->regs->irqstat1);
|
|
|
+ spin_unlock(&dev->lock);
|
|
|
if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) {
|
|
|
if (dev->driver->suspend)
|
|
|
dev->driver->suspend(&dev->gadget);
|
|
@@ -3415,6 +3426,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
|
|
|
dev->driver->resume(&dev->gadget);
|
|
|
/* at high speed, note erratum 0133 */
|
|
|
}
|
|
|
+ spin_lock(&dev->lock);
|
|
|
stat &= ~tmp;
|
|
|
}
|
|
|
|