diff options
author | Peter Chen <peter.chen@freescale.com> | 2010-12-06 13:37:01 +0800 |
---|---|---|
committer | Peter Chen <peter.chen@freescale.com> | 2010-12-07 12:40:01 +0800 |
commit | 39a4339eb829aef051956e9ababf1c0c47a0b559 (patch) | |
tree | 6816e7d1356a90b44973909a7238ecd9976520aa /drivers | |
parent | 7fe39ce482ae515dfece872608978553a3ff8090 (diff) |
ENGR00135975 usb: Add protection for resume routine for udc driver
At usb otg mode, the fsl_udc_resume will be called at otg_set_host and
otg_set_peripheral. So we needs to add mutex_lock for fsl_udc_resume to
protect being called at the same time.
Besides, the fsl_udc_resume should not be called continuous twice, or the
udc->suspended will be wrong
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/arcotg_udc.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c index 86b8900bc48f..bd3aaffe2331 100644 --- a/drivers/usb/gadget/arcotg_udc.c +++ b/drivers/usb/gadget/arcotg_udc.c @@ -70,6 +70,7 @@ #endif #define DMA_ADDR_INVALID (~(dma_addr_t)0) +DEFINE_MUTEX(udc_resume_mutex); extern void usb_debounce_id_pin(void); static const char driver_name[] = "fsl-usb2-udc"; static const char driver_desc[] = DRIVER_DESC; @@ -3162,6 +3163,7 @@ static int fsl_udc_resume(struct platform_device *pdev) struct fsl_usb2_wakeup_platform_data *wake_up_pdata = pdata->wakeup_pdata; printk(KERN_DEBUG "USB Gadget resume begins\n"); + mutex_lock(&udc_resume_mutex); if (pdev->dev.power.status == DPM_RESUMING) { printk(KERN_DEBUG "%s, Wait for wakeup thread finishes\n", __func__); wait_event_interruptible(wake_up_pdata->wq, !wake_up_pdata->usb_wakeup_is_pending); @@ -3170,9 +3172,17 @@ static int fsl_udc_resume(struct platform_device *pdev) pr_debug("%s(): stopped %d suspended %d\n", __func__, udc_controller->stopped, udc_controller->suspended); #ifdef CONFIG_USB_OTG - if (udc_controller->transceiver->gadget == NULL) + if (udc_controller->transceiver->gadget == NULL) { + mutex_unlock(&udc_resume_mutex); return 0; + } #endif + /* Do noop if the udc is already at resume state */ + if (udc_controller->suspended == 0) { + mutex_unlock(&udc_resume_mutex); + return 0; + } + /* * If the controller was stopped at suspend time, then * don't resume it now. @@ -3225,6 +3235,7 @@ end: dr_clk_gate(false); } --udc_controller->suspended; + mutex_unlock(&udc_resume_mutex); printk(KERN_DEBUG "USB Gadget resume ends\n"); return 0; } |