aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi Jun <jun.li@nxp.com>2017-03-06 21:35:01 -0500
committerPeter Chen <peter.chen@nxp.com>2017-03-14 23:30:43 -0400
commit4f4555cfe704913ce4ce836ab2707825d784a7cc (patch)
tree6e6393d5f4bd3fa9c3f16c80d23caf620a1eb2e9
parent4495c08e84729385774601b5146d51d9e5849f81 (diff)
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. Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Peter Chen <peter.chen@nxp.com>
-rw-r--r--drivers/usb/chipidea/ci.h2
-rw-r--r--drivers/usb/chipidea/udc.c21
2 files changed, 15 insertions, 8 deletions
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 59e22389c10b..6743f85b1b7a 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -177,6 +177,7 @@ struct hw_bank {
177 * @td_pool: allocation pool for transfer descriptors 177 * @td_pool: allocation pool for transfer descriptors
178 * @gadget: device side representation for peripheral controller 178 * @gadget: device side representation for peripheral controller
179 * @driver: gadget driver 179 * @driver: gadget driver
180 * @resume_state: save the state of gadget suspend from
180 * @hw_ep_max: total number of endpoints supported by hardware 181 * @hw_ep_max: total number of endpoints supported by hardware
181 * @ci_hw_ep: array of endpoints 182 * @ci_hw_ep: array of endpoints
182 * @ep0_dir: ep0 direction 183 * @ep0_dir: ep0 direction
@@ -227,6 +228,7 @@ struct ci_hdrc {
227 228
228 struct usb_gadget gadget; 229 struct usb_gadget gadget;
229 struct usb_gadget_driver *driver; 230 struct usb_gadget_driver *driver;
231 enum usb_device_state resume_state;
230 unsigned hw_ep_max; 232 unsigned hw_ep_max;
231 struct ci_hw_ep ci_hw_ep[ENDPT_MAX]; 233 struct ci_hw_ep ci_hw_ep[ENDPT_MAX];
232 u32 ep0_dir; 234 u32 ep0_dir;
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index f88e9157fad0..be166c6ecb2d 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1845,27 +1845,32 @@ static irqreturn_t udc_irq(struct ci_hdrc *ci)
1845 if (USBi_PCI & intr) { 1845 if (USBi_PCI & intr) {
1846 ci->gadget.speed = hw_port_is_high_speed(ci) ? 1846 ci->gadget.speed = hw_port_is_high_speed(ci) ?
1847 USB_SPEED_HIGH : USB_SPEED_FULL; 1847 USB_SPEED_HIGH : USB_SPEED_FULL;
1848 if (ci->suspended && ci->driver->resume) { 1848 if (ci->suspended) {
1849 spin_unlock(&ci->lock); 1849 if (ci->driver->resume) {
1850 ci->driver->resume(&ci->gadget); 1850 spin_unlock(&ci->lock);
1851 spin_lock(&ci->lock); 1851 ci->driver->resume(&ci->gadget);
1852 spin_lock(&ci->lock);
1853 }
1852 ci->suspended = 0; 1854 ci->suspended = 0;
1855 usb_gadget_set_state(&ci->gadget,
1856 ci->resume_state);
1853 } 1857 }
1854 } 1858 }
1855 1859
1856 if (USBi_UI & intr) 1860 if (USBi_UI & intr)
1857 isr_tr_complete_handler(ci); 1861 isr_tr_complete_handler(ci);
1858 1862
1859 if (USBi_SLI & intr) { 1863 if ((USBi_SLI & intr) && !(ci->suspended)) {
1864 ci->suspended = 1;
1865 ci->resume_state = ci->gadget.state;
1860 if (ci->gadget.speed != USB_SPEED_UNKNOWN && 1866 if (ci->gadget.speed != USB_SPEED_UNKNOWN &&
1861 ci->driver->suspend) { 1867 ci->driver->suspend) {
1862 ci->suspended = 1;
1863 spin_unlock(&ci->lock); 1868 spin_unlock(&ci->lock);
1864 ci->driver->suspend(&ci->gadget); 1869 ci->driver->suspend(&ci->gadget);
1865 usb_gadget_set_state(&ci->gadget,
1866 USB_STATE_SUSPENDED);
1867 spin_lock(&ci->lock); 1870 spin_lock(&ci->lock);
1868 } 1871 }
1872 usb_gadget_set_state(&ci->gadget,
1873 USB_STATE_SUSPENDED);
1869 } 1874 }
1870 retval = IRQ_HANDLED; 1875 retval = IRQ_HANDLED;
1871 } else { 1876 } else {