From 669adc2f6196c3540ba8a2fd4512761526ba9097 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Sat, 4 Mar 2017 00:30:44 +0800 Subject: [PATCH] MLK-14256 usb: chipidea: udc: update gadget state after bus resume Gadget state is set to be suspended when bus suspened, but not updated after resume, this patch saves the gadget state before suspend and restores it after resume. Acked-by: Peter Chen Signed-off-by: Li Jun --- drivers/usb/chipidea/ci.h | 2 ++ drivers/usb/chipidea/udc.c | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 081a501f4105..9c8d20d5f5c8 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -178,6 +178,7 @@ struct hw_bank { * @td_pool: allocation pool for transfer descriptors * @gadget: device side representation for peripheral controller * @driver: gadget driver + * @resume_state: save the state of gadget suspend from * @hw_ep_max: total number of endpoints supported by hardware * @ci_hw_ep: array of endpoints * @ep0_dir: ep0 direction @@ -227,6 +228,7 @@ struct ci_hdrc { struct usb_gadget gadget; struct usb_gadget_driver *driver; + enum usb_device_state resume_state; unsigned hw_ep_max; struct ci_hw_ep ci_hw_ep[ENDPT_MAX]; u32 ep0_dir; diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 5b4f92c77523..31f7ea1b5123 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1892,27 +1892,32 @@ static irqreturn_t udc_irq(struct ci_hdrc *ci) if (ci->usb_phy) usb_phy_set_event(ci->usb_phy, USB_EVENT_ENUMERATED); - if (ci->suspended && ci->driver->resume) { - spin_unlock(&ci->lock); - ci->driver->resume(&ci->gadget); - spin_lock(&ci->lock); + if (ci->suspended) { + if (ci->driver->resume) { + spin_unlock(&ci->lock); + ci->driver->resume(&ci->gadget); + spin_lock(&ci->lock); + } ci->suspended = 0; + usb_gadget_set_state(&ci->gadget, + ci->resume_state); } } if (USBi_UI & intr) isr_tr_complete_handler(ci); - if (USBi_SLI & intr) { + if ((USBi_SLI & intr) && !(ci->suspended)) { + ci->suspended = 1; + ci->resume_state = ci->gadget.state; if (ci->gadget.speed != USB_SPEED_UNKNOWN && ci->driver->suspend) { - ci->suspended = 1; spin_unlock(&ci->lock); ci->driver->suspend(&ci->gadget); - usb_gadget_set_state(&ci->gadget, - USB_STATE_SUSPENDED); spin_lock(&ci->lock); } + usb_gadget_set_state(&ci->gadget, + USB_STATE_SUSPENDED); } retval = IRQ_HANDLED; } else { -- 2.17.1