Skip to content

Commit 54aaa3b

Browse files
prashk-ossgregkh
authored andcommitted
usb: dwc3: gadget: Move vbus draw to workqueue context
Currently dwc3_gadget_vbus_draw() can be called from atomic context, which in turn invokes power-supply-core APIs. And some these PMIC APIs have operations that may sleep, leading to kernel panic. Fix this by moving the vbus_draw into a workqueue context. Fixes: 99288de ("usb: dwc3: add an alternate path in vbus_draw callback") Cc: stable <stable@kernel.org> Tested-by: Samuel Wu <wusamuel@google.com> Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Prashanth K <prashanth.k@oss.qualcomm.com> Link: https://patch.msgid.link/20260204054155.3063825-1-prashanth.k@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 6dbc394 commit 54aaa3b

3 files changed

Lines changed: 25 additions & 6 deletions

File tree

drivers/usb/dwc3/core.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2155,6 +2155,20 @@ static int dwc3_get_num_ports(struct dwc3 *dwc)
21552155
return 0;
21562156
}
21572157

2158+
static void dwc3_vbus_draw_work(struct work_struct *work)
2159+
{
2160+
struct dwc3 *dwc = container_of(work, struct dwc3, vbus_draw_work);
2161+
union power_supply_propval val = {0};
2162+
int ret;
2163+
2164+
val.intval = 1000 * (dwc->current_limit);
2165+
ret = power_supply_set_property(dwc->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
2166+
2167+
if (ret < 0)
2168+
dev_dbg(dwc->dev, "Error (%d) setting vbus draw (%d mA)\n",
2169+
ret, dwc->current_limit);
2170+
}
2171+
21582172
static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)
21592173
{
21602174
struct power_supply *usb_psy;
@@ -2169,6 +2183,7 @@ static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)
21692183
if (!usb_psy)
21702184
return ERR_PTR(-EPROBE_DEFER);
21712185

2186+
INIT_WORK(&dwc->vbus_draw_work, dwc3_vbus_draw_work);
21722187
return usb_psy;
21732188
}
21742189

@@ -2395,8 +2410,10 @@ void dwc3_core_remove(struct dwc3 *dwc)
23952410

23962411
dwc3_free_event_buffers(dwc);
23972412

2398-
if (dwc->usb_psy)
2413+
if (dwc->usb_psy) {
2414+
cancel_work_sync(&dwc->vbus_draw_work);
23992415
power_supply_put(dwc->usb_psy);
2416+
}
24002417
}
24012418
EXPORT_SYMBOL_GPL(dwc3_core_remove);
24022419

drivers/usb/dwc3/core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,8 @@ struct dwc3_glue_ops {
10581058
* @role_switch_default_mode: default operation mode of controller while
10591059
* usb role is USB_ROLE_NONE.
10601060
* @usb_psy: pointer to power supply interface.
1061+
* @vbus_draw_work: Work to set the vbus drawing limit
1062+
* @current_limit: How much current to draw from vbus, in milliAmperes.
10611063
* @usb2_phy: pointer to USB2 PHY
10621064
* @usb3_phy: pointer to USB3 PHY
10631065
* @usb2_generic_phy: pointer to array of USB2 PHYs
@@ -1244,6 +1246,8 @@ struct dwc3 {
12441246
enum usb_dr_mode role_switch_default_mode;
12451247

12461248
struct power_supply *usb_psy;
1249+
struct work_struct vbus_draw_work;
1250+
unsigned int current_limit;
12471251

12481252
u32 fladj;
12491253
u32 ref_clk_per;

drivers/usb/dwc3/gadget.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3124,19 +3124,17 @@ static void dwc3_gadget_set_ssp_rate(struct usb_gadget *g,
31243124
static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA)
31253125
{
31263126
struct dwc3 *dwc = gadget_to_dwc(g);
3127-
union power_supply_propval val = {0};
3128-
int ret;
31293127

31303128
if (dwc->usb2_phy)
31313129
return usb_phy_set_power(dwc->usb2_phy, mA);
31323130

31333131
if (!dwc->usb_psy)
31343132
return -EOPNOTSUPP;
31353133

3136-
val.intval = 1000 * mA;
3137-
ret = power_supply_set_property(dwc->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
3134+
dwc->current_limit = mA;
3135+
schedule_work(&dwc->vbus_draw_work);
31383136

3139-
return ret;
3137+
return 0;
31403138
}
31413139

31423140
/**

0 commit comments

Comments
 (0)