summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/udc/net2280.c
diff options
context:
space:
mode:
authorAlan Stern2014-11-06 07:27:56 +0100
committerFelipe Balbi2014-11-11 00:19:35 +0100
commitb611e424f1ad189409dde50fe950eb8c05f75cab (patch)
treecb2a6cc0cdcb9b36f31ee1a25c935b2cd50d8a4c /drivers/usb/gadget/udc/net2280.c
parentusb: gadget: dummy-hcd: use udc-core's reset notifier (diff)
downloadkernel-qcow2-linux-b611e424f1ad189409dde50fe950eb8c05f75cab.tar.gz
kernel-qcow2-linux-b611e424f1ad189409dde50fe950eb8c05f75cab.tar.xz
kernel-qcow2-linux-b611e424f1ad189409dde50fe950eb8c05f75cab.zip
usb: gadget: net2280: use udc-core's reset notifier
This patch adds support for the new udc-core reset notifier to the net2280 driver. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/udc/net2280.c')
-rw-r--r--drivers/usb/gadget/udc/net2280.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c
index bd03a1b4192d..c49179493796 100644
--- a/drivers/usb/gadget/udc/net2280.c
+++ b/drivers/usb/gadget/udc/net2280.c
@@ -3308,17 +3308,42 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
* only indicates a change in the reset state).
*/
if (stat & tmp) {
+ bool reset = false;
+ bool disconnect = false;
+
+ /*
+ * Ignore disconnects and resets if the speed hasn't been set.
+ * VBUS can bounce and there's always an initial reset.
+ */
writel(tmp, &dev->regs->irqstat1);
- if ((((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) &&
- ((readl(&dev->usb->usbstat) & mask) == 0)) ||
- ((readl(&dev->usb->usbctl) &
- BIT(VBUS_PIN)) == 0)) &&
- (dev->gadget.speed != USB_SPEED_UNKNOWN)) {
- ep_dbg(dev, "disconnect %s\n",
- dev->driver->driver.name);
- stop_activity(dev, dev->driver);
- ep0_start(dev);
- return;
+ if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
+ if ((stat & BIT(VBUS_INTERRUPT)) &&
+ (readl(&dev->usb->usbctl) &
+ BIT(VBUS_PIN)) == 0) {
+ disconnect = true;
+ ep_dbg(dev, "disconnect %s\n",
+ dev->driver->driver.name);
+ } else if ((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) &&
+ (readl(&dev->usb->usbstat) & mask)
+ == 0) {
+ reset = true;
+ ep_dbg(dev, "reset %s\n",
+ dev->driver->driver.name);
+ }
+
+ 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;
+ }
}
stat &= ~tmp;