On Wed, Jan 15, 2025, Kyle Tso wrote: > Currently, DWC3 driver attempts to acquire the USB power supply only > once during the probe. If the USB power supply is not ready at that > time, the driver simply ignores the failure and continues the probe, > leading to permanent non-functioning of the gadget vbus_draw callback. > > Address this problem by delaying the dwc3 driver initialization until > the USB power supply is registered. > > Fixes: 6f0764b5adea ("usb: dwc3: add a power supply for current control") > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Kyle Tso <kyletso@xxxxxxxxxx> > --- > v1 -> v2: > - get the power supply in a dedicated function > > --- > drivers/usb/dwc3/core.c | 30 +++++++++++++++++++++--------- > 1 file changed, 21 insertions(+), 9 deletions(-) > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > index 7578c5133568..dfa1b5fe48dc 100644 > --- a/drivers/usb/dwc3/core.c > +++ b/drivers/usb/dwc3/core.c > @@ -1684,8 +1684,6 @@ static void dwc3_get_properties(struct dwc3 *dwc) > u8 tx_thr_num_pkt_prd = 0; > u8 tx_max_burst_prd = 0; > u8 tx_fifo_resize_max_num; > - const char *usb_psy_name; > - int ret; > > /* default to highest possible threshold */ > lpm_nyet_threshold = 0xf; > @@ -1720,13 +1718,6 @@ static void dwc3_get_properties(struct dwc3 *dwc) > > dwc->sys_wakeup = device_may_wakeup(dwc->sysdev); > > - ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name); > - if (ret >= 0) { > - dwc->usb_psy = power_supply_get_by_name(usb_psy_name); > - if (!dwc->usb_psy) > - dev_err(dev, "couldn't get usb power supply\n"); > - } > - > dwc->has_lpm_erratum = device_property_read_bool(dev, > "snps,has-lpm-erratum"); > device_property_read_u8(dev, "snps,lpm-nyet-threshold", > @@ -2129,6 +2120,23 @@ static int dwc3_get_num_ports(struct dwc3 *dwc) > return 0; > } > > +static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc) > +{ > + struct power_supply *usb_psy; > + const char *usb_psy_name; > + int ret; > + > + ret = device_property_read_string(dwc->dev, "usb-psy-name", &usb_psy_name); > + if (ret < 0) > + return NULL; > + > + usb_psy = power_supply_get_by_name(usb_psy_name); > + if (!usb_psy) > + return ERR_PTR(-EPROBE_DEFER); > + > + return usb_psy; > +} > + > static int dwc3_probe(struct platform_device *pdev) > { > struct device *dev = &pdev->dev; > @@ -2185,6 +2193,10 @@ static int dwc3_probe(struct platform_device *pdev) > > dwc3_get_software_properties(dwc); > > + dwc->usb_psy = dwc3_get_usb_power_supply(dwc); > + if (IS_ERR(dwc->usb_psy)) > + return dev_err_probe(dev, PTR_ERR(dwc->usb_psy), "couldn't get usb power supply\n"); > + > dwc->reset = devm_reset_control_array_get_optional_shared(dev); > if (IS_ERR(dwc->reset)) { > ret = PTR_ERR(dwc->reset); > -- > 2.48.0.rc2.279.g1de40edade-goog > Acked-by: Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx> Thanks, Thinh