From ec222455e457152dad1c55a7398dca7ff839758f Mon Sep 17 00:00:00 2001 From: William Wu Date: Wed, 9 Dec 2020 15:52:08 +0800 Subject: [PATCH] usb: dwc3: gadget: fix time out waiting for setup phase when stop gadget If dwc3 failed to init ep0 in __dwc3_gadget_start(), the ep0state will be uninitialized, aka, ep0state is EP0_UNCONNECTED, in this case, we don't need to wait for control transfer completion when stop gadget because no usb control transfer in process. This patch can help to avoid the following warning in RK356x Boards during shutdown process. [ 30.735323] usb ffs open D 0 309 1 0x0400002d [ 30.735330] Call trace: [ 30.735336] __switch_to+0xe4/0x138 [ 30.735348] __schedule+0x2f4/0x930 [ 30.735358] schedule+0x38/0xa0 [ 30.735368] schedule_timeout+0x194/0x478 [ 30.735378] wait_for_common+0x130/0x1e8 [ 30.735388] wait_for_completion_timeout+0x10/0x18 [ 30.735399] dwc3_gadget_pullup+0x68/0xc8 [ 30.735411] usb_gadget_disconnect+0xf0/0x110 [ 30.735422] usb_gadget_remove_driver+0x24/0x70 [ 30.735431] usb_gadget_unregister_driver+0xd0/0x120 [ 30.735441] unregister_gadget+0x20/0x50 [ 30.735450] unregister_gadget_item+0x24/0x38 [ 30.735461] ffs_data_clear+0x120/0x130 [ 30.735471] ffs_data_reset+0x14/0x58 [ 30.735480] ffs_data_closed+0x88/0xd8 [ 30.735490] ffs_ep0_release+0x10/0x20 [ 30.735501] __fput+0x88/0x1b8 [ 30.735510] ____fput+0xc/0x18 [ 30.735521] task_work_run+0x94/0xb0 [ 30.735531] do_exit+0x334/0xa28 [ 30.735540] do_group_exit+0x34/0x98 [ 30.735550] get_signal+0xe4/0x828 [ 30.735557] do_signal+0x1c0/0x298 [ 30.735563] do_notify_resume+0xd0/0x118 [ 30.735568] work_pending+0x8/0x10 [ 30.735602] sysrq: Kill All Tasks Change-Id: I3534b710804e099d857149b0b0b58a7a7236b8fc Signed-off-by: William Wu --- drivers/usb/dwc3/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index deb51e988289..bb65ddacc1ea 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2471,7 +2471,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) * Per databook, when we want to stop the gadget, if a control transfer * is still in process, complete it and get the core into setup phase. */ - if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) { + if (!is_on && dwc->ep0state != EP0_SETUP_PHASE && + dwc->ep0state != EP0_UNCONNECTED) { reinit_completion(&dwc->ep0_in_setup); ret = wait_for_completion_timeout(&dwc->ep0_in_setup,