diff mbox series

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

Message ID 20250114141607.2091154-1-kyletso@google.com (mailing list archive)
State Superseded
Headers show
Series [v1] usb: dwc3: core: Defer the probe until USB power supply ready | expand

Commit Message

Kyle Tso Jan. 14, 2025, 2:16 p.m. UTC
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@vger.kernel.org
Signed-off-by: Kyle Tso <kyletso@google.com>
---
Note: This is a follow-up of https://lore.kernel.org/all/20240804084612.2561230-1-kyletso@google.com/
---
 drivers/usb/dwc3/core.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Comments

Thinh Nguyen Jan. 15, 2025, 1:23 a.m. UTC | #1
On Tue, Jan 14, 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@vger.kernel.org
> Signed-off-by: Kyle Tso <kyletso@google.com>
> ---
> Note: This is a follow-up of https://urldefense.com/v3/__https://lore.kernel.org/all/20240804084612.2561230-1-kyletso@google.com/__;!!A4F2R9G_pg!ZTwcKSid-i7kN4_N622H1QDeC3jzi0uCKRqjzrTNStFGr8guMe3xY0EF30CnGGPyBK25ZCGgUc_Wg3koxwqa$ 
> ---
>  drivers/usb/dwc3/core.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 7578c5133568..1550c39e792a 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -1669,7 +1669,7 @@ static void dwc3_get_software_properties(struct dwc3 *dwc)
>  	}
>  }
>  
> -static void dwc3_get_properties(struct dwc3 *dwc)
> +static int dwc3_get_properties(struct dwc3 *dwc)

It doesn't make sense for dwc3_get_properties() to return -EPROBE_DEFER.

>  {
>  	struct device		*dev = dwc->dev;
>  	u8			lpm_nyet_threshold;
> @@ -1724,7 +1724,7 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>  	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");
> +			return dev_err_probe(dev, -EPROBE_DEFER, "couldn't get usb power supply\n");
>  	}

Move this logic (including power_supply_get_by_name()) outside of
dwc3_get_properties(). It doesn't belong here.

Thanks,
Thinh

>  
>  	dwc->has_lpm_erratum = device_property_read_bool(dev,
> @@ -1847,6 +1847,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>  	dwc->imod_interval = 0;
>  
>  	dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num;
> +
> +	return 0;
>  }
>  
>  /* check whether the core supports IMOD */
> @@ -2181,7 +2183,9 @@ static int dwc3_probe(struct platform_device *pdev)
>  	dwc->regs	= regs;
>  	dwc->regs_size	= resource_size(&dwc_res);
>  
> -	dwc3_get_properties(dwc);
> +	ret = dwc3_get_properties(dwc);
> +	if (ret)
> +		return ret;
>  
>  	dwc3_get_software_properties(dwc);
>  
> -- 
> 2.47.1.688.g23fc6f90ad-goog
>
diff mbox series

Patch

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 7578c5133568..1550c39e792a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1669,7 +1669,7 @@  static void dwc3_get_software_properties(struct dwc3 *dwc)
 	}
 }
 
-static void dwc3_get_properties(struct dwc3 *dwc)
+static int dwc3_get_properties(struct dwc3 *dwc)
 {
 	struct device		*dev = dwc->dev;
 	u8			lpm_nyet_threshold;
@@ -1724,7 +1724,7 @@  static void dwc3_get_properties(struct dwc3 *dwc)
 	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");
+			return dev_err_probe(dev, -EPROBE_DEFER, "couldn't get usb power supply\n");
 	}
 
 	dwc->has_lpm_erratum = device_property_read_bool(dev,
@@ -1847,6 +1847,8 @@  static void dwc3_get_properties(struct dwc3 *dwc)
 	dwc->imod_interval = 0;
 
 	dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num;
+
+	return 0;
 }
 
 /* check whether the core supports IMOD */
@@ -2181,7 +2183,9 @@  static int dwc3_probe(struct platform_device *pdev)
 	dwc->regs	= regs;
 	dwc->regs_size	= resource_size(&dwc_res);
 
-	dwc3_get_properties(dwc);
+	ret = dwc3_get_properties(dwc);
+	if (ret)
+		return ret;
 
 	dwc3_get_software_properties(dwc);