diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 99d817296208..ddf35953dc49 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1256,6 +1256,19 @@ static int dwc3_probe(struct platform_device *pdev) dwc3_get_properties(dwc); + if (dwc->dr_mode == USB_DR_MODE_OTG) { + dwc->otg_caps.otg_rev = 0x0300; + dwc->otg_caps.hnp_support = true; + dwc->otg_caps.srp_support = true; + dwc->otg_caps.adp_support = true; + + /* Update otg capabilities by DT properties */ + ret = of_usb_update_otg_caps(dev->of_node, + &dwc->otg_caps); + if (ret) + goto err0; + } + platform_set_drvdata(pdev, dwc); dwc3_cache_hwparams(dwc); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 6d4d9b14f98b..090c8645078d 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -872,6 +872,7 @@ struct dwc3_scratchpad_array { * 3 - Reserved * @imod_interval: set the interrupt moderation interval in 250ns * increments or 0 to disable. + * @otg_caps: the OTG capabilities from hardware point */ struct dwc3 { struct work_struct drd_work; @@ -1027,6 +1028,8 @@ struct dwc3 { unsigned tx_de_emphasis:2; u16 imod_interval; + + struct usb_otg_caps otg_caps; }; #define work_to_dwc(w) (container_of((w), struct dwc3, drd_work)) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 176739d7e19f..8f7ecaf684f7 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3251,7 +3251,10 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc->gadget.speed = USB_SPEED_UNKNOWN; dwc->gadget.sg_supported = true; dwc->gadget.name = "dwc3-gadget"; - dwc->gadget.is_otg = dwc->dr_mode == USB_DR_MODE_OTG; + dwc->gadget.is_otg = (dwc->dr_mode == USB_DR_MODE_OTG) && + (dwc->otg_caps.hnp_support || + dwc->otg_caps.srp_support || + dwc->otg_caps.adp_support); /* * FIXME We might be setting max_speed to