On 12/13/2016 11:12 AM, John Stultz wrote: > 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 > erroniously 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. > > I suspect this isn't the best solution, but it seems to work > well for me. > > Feedback would be greatly appreciated! > > Cc: Wei Xu <xuwei5@xxxxxxxxxxxxx> > Cc: Guodong Xu <guodong.xu@xxxxxxxxxx> > Cc: Amit Pundir <amit.pundir@xxxxxxxxxx> > Cc: Rob Herring <robh+dt@xxxxxxxxxx> > Cc: John Youn <johnyoun@xxxxxxxxxxxx> > Cc: Douglas Anderson <dianders@xxxxxxxxxxxx> > Cc: Chen Yu <chenyu56@xxxxxxxxxx> > Cc: Kishon Vijay Abraham I <kishon@xxxxxx> > Cc: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx> > Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> > Cc: linux-usb@xxxxxxxxxxxxxxx > Acked-by: John Youn <johnyoun@xxxxxxxxxxxx> > Signed-off-by: John Stultz <john.stultz@xxxxxxxxxx> > --- > drivers/usb/dwc2/hcd.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c > index df5a065..a3f34dd 100644 > --- a/drivers/usb/dwc2/hcd.c > +++ b/drivers/usb/dwc2/hcd.c > @@ -3199,7 +3199,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) > dev_dbg(hsotg->dev, "gotgctl=%0x\n", gotgctl); > dev_dbg(hsotg->dev, "gotgctl.b.conidsts=%d\n", > !!(gotgctl & GOTGCTL_CONID_B)); > - > +again: > /* B-Device connector (Device Mode) */ > if (gotgctl & GOTGCTL_CONID_B) { > /* Wait for switch to device mode */ > @@ -3210,6 +3210,9 @@ static void dwc2_conn_id_status_change(struct work_struct *work) > dwc2_is_host_mode(hsotg) ? "Host" : > "Peripheral"); > usleep_range(20000, 40000); > + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); > + if (!(gotgctl & GOTGCTL_CONID_B)) > + goto again; > if (++count > 250) > break; > } > Hi John Stultz, When it goes to ":again", it will go to else anyways. I'll suggest alternative way to do this. Please see below. Also you can add "Reviewed-by: Vardan Mikayelyan <mvardan@xxxxxxxxxxxx>" Thanks, Vardan. diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index b7311a6..128311b 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3242,6 +3242,9 @@ static void dwc2_conn_id_status_change(struct work_struct *work) dwc2_is_host_mode(hsotg) ? "Host" : "Peripheral"); usleep_range(20000, 40000); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); + if (!(gotgctl & GOTGCTL_CONID_B)) + goto host; if (++count > 250) break; } @@ -3256,6 +3259,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)) { -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html