Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: dwc3: core: Defer the probe until USB power supply ready

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 <stable@kernel.org>
Signed-off-by: Kyle Tso <kyletso@google.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/20250115044548.2701138-1-kyletso@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Kyle Tso and committed by
Greg Kroah-Hartman
66e0ea34 81702d41

+21 -9
+21 -9
drivers/usb/dwc3/core.c
··· 1684 1684 u8 tx_thr_num_pkt_prd = 0; 1685 1685 u8 tx_max_burst_prd = 0; 1686 1686 u8 tx_fifo_resize_max_num; 1687 - const char *usb_psy_name; 1688 - int ret; 1689 1687 1690 1688 /* default to highest possible threshold */ 1691 1689 lpm_nyet_threshold = 0xf; ··· 1717 1719 dwc->sysdev = dwc->dev; 1718 1720 1719 1721 dwc->sys_wakeup = device_may_wakeup(dwc->sysdev); 1720 - 1721 - ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name); 1722 - if (ret >= 0) { 1723 - dwc->usb_psy = power_supply_get_by_name(usb_psy_name); 1724 - if (!dwc->usb_psy) 1725 - dev_err(dev, "couldn't get usb power supply\n"); 1726 - } 1727 1722 1728 1723 dwc->has_lpm_erratum = device_property_read_bool(dev, 1729 1724 "snps,has-lpm-erratum"); ··· 2120 2129 return 0; 2121 2130 } 2122 2131 2132 + static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc) 2133 + { 2134 + struct power_supply *usb_psy; 2135 + const char *usb_psy_name; 2136 + int ret; 2137 + 2138 + ret = device_property_read_string(dwc->dev, "usb-psy-name", &usb_psy_name); 2139 + if (ret < 0) 2140 + return NULL; 2141 + 2142 + usb_psy = power_supply_get_by_name(usb_psy_name); 2143 + if (!usb_psy) 2144 + return ERR_PTR(-EPROBE_DEFER); 2145 + 2146 + return usb_psy; 2147 + } 2148 + 2123 2149 static int dwc3_probe(struct platform_device *pdev) 2124 2150 { 2125 2151 struct device *dev = &pdev->dev; ··· 2192 2184 dwc3_get_properties(dwc); 2193 2185 2194 2186 dwc3_get_software_properties(dwc); 2187 + 2188 + dwc->usb_psy = dwc3_get_usb_power_supply(dwc); 2189 + if (IS_ERR(dwc->usb_psy)) 2190 + return dev_err_probe(dev, PTR_ERR(dwc->usb_psy), "couldn't get usb power supply\n"); 2195 2191 2196 2192 dwc->reset = devm_reset_control_array_get_optional_shared(dev); 2197 2193 if (IS_ERR(dwc->reset)) {