Skip to content

Commit b9f8f66

Browse files
kyletsoadlgregkh
authored andcommitted
usb: dwc3: core: Defer the probe until USB power supply ready
commit 66e0ea3 upstream. 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: 6f0764b ("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>
1 parent 2228733 commit b9f8f66

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

drivers/usb/dwc3/core.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,8 +1664,6 @@ static void dwc3_get_properties(struct dwc3 *dwc)
16641664
u8 tx_thr_num_pkt_prd = 0;
16651665
u8 tx_max_burst_prd = 0;
16661666
u8 tx_fifo_resize_max_num;
1667-
const char *usb_psy_name;
1668-
int ret;
16691667

16701668
/* default to highest possible threshold */
16711669
lpm_nyet_threshold = 0xf;
@@ -1700,13 +1698,6 @@ static void dwc3_get_properties(struct dwc3 *dwc)
17001698

17011699
dwc->sys_wakeup = device_may_wakeup(dwc->sysdev);
17021700

1703-
ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name);
1704-
if (ret >= 0) {
1705-
dwc->usb_psy = power_supply_get_by_name(usb_psy_name);
1706-
if (!dwc->usb_psy)
1707-
dev_err(dev, "couldn't get usb power supply\n");
1708-
}
1709-
17101701
dwc->has_lpm_erratum = device_property_read_bool(dev,
17111702
"snps,has-lpm-erratum");
17121703
device_property_read_u8(dev, "snps,lpm-nyet-threshold",
@@ -2109,6 +2100,23 @@ static int dwc3_get_num_ports(struct dwc3 *dwc)
21092100
return 0;
21102101
}
21112102

2103+
static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)
2104+
{
2105+
struct power_supply *usb_psy;
2106+
const char *usb_psy_name;
2107+
int ret;
2108+
2109+
ret = device_property_read_string(dwc->dev, "usb-psy-name", &usb_psy_name);
2110+
if (ret < 0)
2111+
return NULL;
2112+
2113+
usb_psy = power_supply_get_by_name(usb_psy_name);
2114+
if (!usb_psy)
2115+
return ERR_PTR(-EPROBE_DEFER);
2116+
2117+
return usb_psy;
2118+
}
2119+
21122120
static int dwc3_probe(struct platform_device *pdev)
21132121
{
21142122
struct device *dev = &pdev->dev;
@@ -2165,6 +2173,10 @@ static int dwc3_probe(struct platform_device *pdev)
21652173

21662174
dwc3_get_software_properties(dwc);
21672175

2176+
dwc->usb_psy = dwc3_get_usb_power_supply(dwc);
2177+
if (IS_ERR(dwc->usb_psy))
2178+
return dev_err_probe(dev, PTR_ERR(dwc->usb_psy), "couldn't get usb power supply\n");
2179+
21682180
dwc->reset = devm_reset_control_array_get_optional_shared(dev);
21692181
if (IS_ERR(dwc->reset)) {
21702182
ret = PTR_ERR(dwc->reset);

0 commit comments

Comments
 (0)