From f1c95218b2d592e618144d139ce123653d79bf20 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 00271cf32c8a..14661fe87644 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2032,7 +2032,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,