mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-26 15:54:18 +08:00
usb: dwc3: core: remove lock of otg mode during gadget suspend/resume to avoid deadlock
When config CONFIG_USB_DWC3_DUAL_ROLE is selected, and trigger system to enter suspend status with below command: echo mem > /sys/power/state There will be a deadlock issue occurring. Detailed invoking path as below: dwc3_suspend_common() spin_lock_irqsave(&dwc->lock, flags); <-- 1st dwc3_gadget_suspend(dwc); dwc3_gadget_soft_disconnect(dwc); spin_lock_irqsave(&dwc->lock, flags); <-- 2nd This issue is exposed by commitc7ebd8149e
("usb: dwc3: gadget: Fix NULL pointer dereference in dwc3_gadget_suspend") that removes the code of checking whether dwc->gadget_driver is NULL or not. It causes the following code is executed and deadlock occurs when trying to get the spinlock. In fact, the root cause is the commit 5265397f9442("usb: dwc3: Remove DWC3 locking during gadget suspend/resume") that forgot to remove the lock of otg mode. So, remove the redundant lock of otg mode during gadget suspend/resume. Fixes:5265397f94
("usb: dwc3: Remove DWC3 locking during gadget suspend/resume") Cc: Xu Yang <xu.yang_2@nxp.com> Cc: stable@vger.kernel.org Signed-off-by: Meng Li <Meng.Li@windriver.com> Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/20240618031918.2585799-1-Meng.Li@windriver.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c68942624e
commit
7838de15bb
@ -2250,7 +2250,6 @@ assert_reset:
|
||||
|
||||
static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
int i;
|
||||
|
||||
@ -2293,9 +2292,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
break;
|
||||
|
||||
if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
|
||||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
dwc3_gadget_suspend(dwc);
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
synchronize_irq(dwc->irq_gadget);
|
||||
}
|
||||
|
||||
@ -2312,7 +2309,6 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
|
||||
static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
u32 reg;
|
||||
int i;
|
||||
@ -2366,9 +2362,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) {
|
||||
dwc3_otg_host_init(dwc);
|
||||
} else if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
|
||||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
dwc3_gadget_resume(dwc);
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
}
|
||||
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user