It is possible that the usb power_supply is registered after the probe of dwc3. In this case, trying to get the usb power_supply during the probe will fail and there is no chance to try again. Also the usb power_supply might be unregistered at anytime so that the handle of it in dwc3 would become invalid. To fix this, get the handle right before calling to power_supply functions and put it afterward.
Fixes: 6f0764b5adea ("usb: dwc3: add a power supply for current control") Cc: stable@vger.kernel.org Signed-off-by: Kyle Tso kyletso@google.com --- drivers/usb/dwc3/core.c | 25 +++++-------------------- drivers/usb/dwc3/core.h | 4 ++-- drivers/usb/dwc3/gadget.c | 19 ++++++++++++++----- 3 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 734de2a8bd21..ab563edd9b4c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1631,8 +1631,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; @@ -1667,12 +1665,7 @@ 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"); - } + device_property_read_string(dev, "usb-psy-name", &dwc->usb_psy_name);
dwc->has_lpm_erratum = device_property_read_bool(dev, "snps,has-lpm-erratum"); @@ -2133,18 +2126,16 @@ static int dwc3_probe(struct platform_device *pdev) dwc3_get_software_properties(dwc);
dwc->reset = devm_reset_control_array_get_optional_shared(dev); - if (IS_ERR(dwc->reset)) { - ret = PTR_ERR(dwc->reset); - goto err_put_psy; - } + if (IS_ERR(dwc->reset)) + return PTR_ERR(dwc->reset);
ret = dwc3_get_clocks(dwc); if (ret) - goto err_put_psy; + return ret;
ret = reset_control_deassert(dwc->reset); if (ret) - goto err_put_psy; + return ret;
ret = dwc3_clk_enable(dwc); if (ret) @@ -2245,9 +2236,6 @@ static int dwc3_probe(struct platform_device *pdev) dwc3_clk_disable(dwc); err_assert_reset: reset_control_assert(dwc->reset); -err_put_psy: - if (dwc->usb_psy) - power_supply_put(dwc->usb_psy);
return ret; } @@ -2276,9 +2264,6 @@ static void dwc3_remove(struct platform_device *pdev) pm_runtime_set_suspended(&pdev->dev);
dwc3_free_event_buffers(dwc); - - if (dwc->usb_psy) - power_supply_put(dwc->usb_psy); }
#ifdef CONFIG_PM diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 1e561fd8b86e..ecfe2cc224f7 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1045,7 +1045,7 @@ struct dwc3_scratchpad_array { * @role_sw: usb_role_switch handle * @role_switch_default_mode: default operation mode of controller while * usb role is USB_ROLE_NONE. - * @usb_psy: pointer to power supply interface. + * @usb_psy_name: name of the usb power supply interface. * @usb2_phy: pointer to USB2 PHY * @usb3_phy: pointer to USB3 PHY * @usb2_generic_phy: pointer to array of USB2 PHYs @@ -1223,7 +1223,7 @@ struct dwc3 { struct usb_role_switch *role_sw; enum usb_dr_mode role_switch_default_mode;
- struct power_supply *usb_psy; + const char *usb_psy_name;
u32 fladj; u32 ref_clk_per; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 89fc690fdf34..c89b5b5a64cf 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3049,20 +3049,29 @@ static void dwc3_gadget_set_ssp_rate(struct usb_gadget *g,
static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA) { - struct dwc3 *dwc = gadget_to_dwc(g); + struct dwc3 *dwc = gadget_to_dwc(g); + struct power_supply *usb_psy; union power_supply_propval val = {0}; int ret;
if (dwc->usb2_phy) return usb_phy_set_power(dwc->usb2_phy, mA);
- if (!dwc->usb_psy) + if (!dwc->usb_psy_name) return -EOPNOTSUPP;
- val.intval = 1000 * mA; - ret = power_supply_set_property(dwc->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val); + usb_psy = power_supply_get_by_name(dwc->usb_psy_name); + if (usb_psy) { + val.intval = 1000 * mA; + ret = power_supply_set_property(usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, + &val); + power_supply_put(usb_psy); + return ret; + }
- return ret; + dev_err(dwc->dev, "couldn't get usb power supply\n"); + + return -EOPNOTSUPP; }
/**
On Mon, Jul 15, 2024 at 10:58:27AM +0800, Kyle Tso wrote:
It is possible that the usb power_supply is registered after the probe of dwc3. In this case, trying to get the usb power_supply during the probe will fail and there is no chance to try again. Also the usb power_supply might be unregistered at anytime so that the handle of it in dwc3 would become invalid. To fix this, get the handle right before calling to power_supply functions and put it afterward.
Fixes: 6f0764b5adea ("usb: dwc3: add a power supply for current control") Cc: stable@vger.kernel.org Signed-off-by: Kyle Tso kyletso@google.com
drivers/usb/dwc3/core.c | 25 +++++-------------------- drivers/usb/dwc3/core.h | 4 ++-- drivers/usb/dwc3/gadget.c | 19 ++++++++++++++----- 3 files changed, 21 insertions(+), 27 deletions(-)
Did this get lost somewhere? You might need to resend it now that Thinh is back from vacation.
thanks,
greg k-h
Hi Greg,
On Wed, Sep 11, 2024, Greg KH wrote:
On Mon, Jul 15, 2024 at 10:58:27AM +0800, Kyle Tso wrote:
It is possible that the usb power_supply is registered after the probe of dwc3. In this case, trying to get the usb power_supply during the probe will fail and there is no chance to try again. Also the usb power_supply might be unregistered at anytime so that the handle of it in dwc3 would become invalid. To fix this, get the handle right before calling to power_supply functions and put it afterward.
Fixes: 6f0764b5adea ("usb: dwc3: add a power supply for current control") Cc: stable@vger.kernel.org Signed-off-by: Kyle Tso kyletso@google.com
drivers/usb/dwc3/core.c | 25 +++++-------------------- drivers/usb/dwc3/core.h | 4 ++-- drivers/usb/dwc3/gadget.c | 19 ++++++++++++++----- 3 files changed, 21 insertions(+), 27 deletions(-)
Did this get lost somewhere? You might need to resend it now that Thinh is back from vacation.
You're looking at the outdated patch. Here's where we left off from the last discussion on v3 of this:
https://lore.kernel.org/linux-usb/20240810005634.6ig2e3hdsgx3wkan@synopsys.c...
BR, Thinh
linux-stable-mirror@lists.linaro.org