Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
usb: dwc_otg_310: fix bad unlock balance issue
There is a bad unlock balance issue in the following case: 1. Use micro USB 2.0 interface; 2. Vbus 5v is always powered on; 3. Wait until DWC2 completes initialization, and then plug in OTG to Host cable; 4. Plug out the OTG cable, and then we will reproduce this issue, and we'll get the following log if we enable the kernel lock debugging. ===================================== [ BUG: bad unlock balance detected! ] 4.4.71 torvalds#303 Not tainted ------------------------------------- swapper/0/0 is trying to release lock (&(sl)->rlock) at: [<c0795848>] dwc_otg_pcd_suspend_cb+0x20/0x48 but there are no more locks to release! other info that might help us debug this: 1 lock held by swapper/0/0: stack backtrace: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.71 torvalds#303 Hardware name: Rockchip (Device Tree) [<c0110018>] (unwind_backtrace) from [<c010c04c>] (show_stack+0x10/0x14) [<c010c04c>] (show_stack) from [<c0423e28>] (dump_stack+0x9c/0xd4) [<c0423e28>] (dump_stack) from [<c021803c>] (print_unlock_imbalance_bug.part.7+0x8c/0xb8) [<c021803c>] (print_unlock_imbalance_bug.part.7) from [<c018ce74>] (lock_release+0x284/0x54c) [<c018ce74>] (lock_release) from [<c0c0e03c>] (_raw_spin_unlock+0x18/0x54) [<c0c0e03c>] (_raw_spin_unlock) from [<c0795848>] (dwc_otg_pcd_suspend_cb+0x20/0x48) [<c0795848>] (dwc_otg_pcd_suspend_cb) from [<c0792cc4>] (dwc_otg_handle_usb_suspend_intr+0x68/0x37c) [<c0792cc4>] (dwc_otg_handle_usb_suspend_intr) from [<c079329c>] (dwc_otg_handle_common_intr+0x2c4/0xd58) [<c079329c>] (dwc_otg_handle_common_intr) from [<c0786a18>] (dwc_otg_common_irq+0xc/0x18) [<c0786a18>] (dwc_otg_common_irq) from [<c0199e48>] (handle_irq_event_percpu+0x188/0x4d4) [<c0199e48>] (handle_irq_event_percpu) from [<c019a1cc>] (handle_irq_event+0x38/0x5c) [<c019a1cc>] (handle_irq_event) from [<c019d654>] (handle_fasteoi_irq+0xa8/0x124) [<c019d654>] (handle_fasteoi_irq) from [<c0199454>] (generic_handle_irq+0x18/0x28) [<c0199454>] (generic_handle_irq) from [<c0199754>] (__handle_domain_irq+0x88/0xb0) [<c0199754>] (__handle_domain_irq) from [<c01014b4>] (gic_handle_irq+0x4c/0x94) [<c01014b4>] (gic_handle_irq) from [<c010cbb8>] (__irq_svc+0x58/0x98) It's because that when plug in OTG to host cable, the core_if->lock will be initialized to hcd->lock (check_id()-> id_status_change()->cil_hcd_start()->dwc_otg_hcd_reinit()), so we should release core_if->lock before call cil_pcd_suspend() rather than release the pcd->lock inside of callback function. Change-Id: I1e32f37c701d1a8d741947b6bf385c1bbcb6da78 Signed-off-by: William Wu <[email protected]>
- Loading branch information