From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753519AbcLMM2X convert rfc822-to-8bit (ORCPT ); Tue, 13 Dec 2016 07:28:23 -0500 Received: from smtprelay.synopsys.com ([198.182.60.111]:42424 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753234AbcLMM2V (ORCPT ); Tue, 13 Dec 2016 07:28:21 -0500 From: Vardan Mikayelyan To: John Stultz , lkml CC: Wei Xu , Guodong Xu , "Amit Pundir" , Rob Herring , John Youn , Douglas Anderson , Chen Yu , Kishon Vijay Abraham I , Felipe Balbi , Greg Kroah-Hartman , "linux-usb@vger.kernel.org" Subject: Re: [RFC][PATCH 2/5] usb: dwc2: Workaround case where GOTGCTL state is wrong Thread-Topic: [RFC][PATCH 2/5] usb: dwc2: Workaround case where GOTGCTL state is wrong Thread-Index: AQHSVRA0dAuzj7sjo0K92exYhrakvw== Date: Tue, 13 Dec 2016 12:28:15 +0000 Message-ID: References: <1481612990-23409-1-git-send-email-john.stultz@linaro.org> <1481612990-23409-3-git-send-email-john.stultz@linaro.org> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.12.239.235] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 > Cc: Guodong Xu > Cc: Amit Pundir > Cc: Rob Herring > Cc: John Youn > Cc: Douglas Anderson > Cc: Chen Yu > Cc: Kishon Vijay Abraham I > Cc: Felipe Balbi > Cc: Greg Kroah-Hartman > Cc: linux-usb@vger.kernel.org > Acked-by: John Youn > Signed-off-by: John Stultz > --- > 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 " 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)) {