From 90834d3ecb952f8f0ab8a5687e58c472935a4e70 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:27:59 +0800 Subject: [PATCH] usb: gadget: pxa25x_udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa25x_udc.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 2944092cd92e..8664b99f147f 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -1283,6 +1283,33 @@ static int pxa25x_udc_start(struct usb_gadget *g, return retval; } +static void +reset_gadget(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) +{ + int i; + + /* don't disconnect drivers more than once */ + if (dev->gadget.speed == USB_SPEED_UNKNOWN) + driver = NULL; + dev->gadget.speed = USB_SPEED_UNKNOWN; + + /* prevent new request submissions, kill any outstanding requests */ + for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { + struct pxa25x_ep *ep = &dev->ep[i]; + + ep->stopped = 1; + nuke(ep, -ESHUTDOWN); + } + del_timer_sync(&dev->timer); + + /* report reset; the driver is already quiesced */ + if (driver) + usb_gadget_udc_reset(&dev->gadget, driver); + + /* re-init driver-visible data structures */ + udc_reinit(dev); +} + static void stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) { @@ -1721,7 +1748,7 @@ pxa25x_udc_irq(int irq, void *_dev) /* reset driver and endpoints, * in case that's not yet done */ - stop_activity (dev, dev->driver); + reset_gadget(dev, dev->driver); } else { DBG(DBG_VERBOSE, "USB reset end\n");