Hi Felipe, On Mon, Dec 02, 2019 at 09:41:42AM +0200, Felipe Balbi wrote: > > Hi, > > Roger Quadros <rogerq@xxxxxx> writes: > > On 18/11/2019 09:07, Felipe Balbi wrote: > >> Hi, > >> > >> Bin Liu <b-liu@xxxxxx> writes: > >> > >>> VBUS should be turned off when leaving the host mode. > >>> Set GCTL_PRTCAP to device mode in teardown to de-assert DRVVBUS pin to > >>> turn off VBUS power. > >>> > >>> Fixes: 5f94adfeed97 ("usb: dwc3: core: refactor mode initialization to its own function") > >>> Signed-off-by: Bin Liu <b-liu@xxxxxx> > >>> --- > >>> drivers/usb/dwc3/core.c | 1 + > >>> 1 file changed, 1 insertion(+) > >>> > >>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > >>> index 97d6ae3c4df2..76ac9cd54e64 100644 > >>> --- a/drivers/usb/dwc3/core.c > >>> +++ b/drivers/usb/dwc3/core.c > >>> @@ -1201,6 +1201,7 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc) > >>> break; > >>> case USB_DR_MODE_HOST: > >>> dwc3_host_exit(dwc); > >>> + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); > >> > >> seems like this should be done as part of dwc3_host_exit() > >> > > > > That wouldn't work well with OTG case as dwc3_host_exit(dwc) is > > called when switching roles and we don't want PRTCAP > > to change from DWC3_GCTL_PRTCAP_OTG. > > if (port != OTG) > set_prtcap(DEVICE) During init, the PRTCAP is set in dwc3_core_init_mode() besides dwc3_{host,gadget,drd}_init(). So for tearing down setting it in dwc3_core_exit_mode() would make the code logic symmetric and easy to understand. Also it turns out that setting PRTCAP is required for OTG mode too to de-assert DRVVBUS. If left GCTL[PRTCAP] to OTG, grounding the ID pin would make the controller to assert DRVVBUS without any software involved. So the fix should be the following. Please let me know you comments. -Bin. -----------8<------------ diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 97d6ae3c4df2..cede7a8e3605 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1209,6 +1209,9 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc) /* do nothing */ break; } + + /* de-assert DRVVBUS for HOST and OTG mode */ + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); } static void dwc3_get_properties(struct dwc3 *dwc) > > -- > balbi