UPSTREAM: usb: dwc2: Workaround case where GOTGCTL state is wrong
When removing a USB-A to USB-otg adapter cable, we get a change status
irq, and then in dwc2_conn_id_status_change, we erroneously see the
GOTGCTL_CONID_B flag set. This causes us to get stuck in the
"while (!dwc2_is_device_mode(hsotg))" loop, spitting out "Waiting for
Peripheral Mode, Mode=Host" warnings until it fails out many seconds
later.
This patch works around the issue by re-reading the GOTGCTL state to
check if the GOTGCTL_CONID_B is still set and if not restarting the
change status logic.
Change-Id: If75fea4e81d40413dca696750873ba7e51d6b105
Cc: Wei Xu <xuwei5@hisilicon.com>
Cc: Guodong Xu <guodong.xu@linaro.org>
Cc: Amit Pundir <amit.pundir@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: John Youn <johnyoun@synopsys.com>
Cc: Douglas Anderson <dianders@chromium.org>
Cc: Chen Yu <chenyu56@huawei.com>
Cc: Vardan Mikayelyan <mvardan@synopsys.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Felipe Balbi <felipe.balbi@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-usb@vger.kernel.org
Reviewed-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: William Wu <william.wu@rock-chips.com>
(cherry picked from commit fc30c4bb44)
This commit is contained in:
parent
a875efed49
commit
17a558fa5e
1 changed files with 9 additions and 0 deletions
|
|
@ -3212,6 +3212,14 @@ static void dwc2_conn_id_status_change(struct work_struct *work)
|
|||
dwc2_is_host_mode(hsotg) ? "Host" :
|
||||
"Peripheral");
|
||||
msleep(20);
|
||||
/*
|
||||
* Sometimes the initial GOTGCTRL read is wrong, so
|
||||
* check it again and jump to host mode if that was
|
||||
* the case.
|
||||
*/
|
||||
gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
|
||||
if (!(gotgctl & GOTGCTL_CONID_B))
|
||||
goto host;
|
||||
if (++count > 250)
|
||||
break;
|
||||
}
|
||||
|
|
@ -3226,6 +3234,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work)
|
|||
spin_unlock_irqrestore(&hsotg->lock, flags);
|
||||
dwc2_hsotg_core_connect(hsotg);
|
||||
} else {
|
||||
host:
|
||||
/* A-Device connector (Host Mode) */
|
||||
dev_dbg(hsotg->dev, "connId A\n");
|
||||
while (!dwc2_is_host_mode(hsotg)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue