FAILED: Patch "usb: dwc3: gadget: Move vbus draw to workqueue context" failed to apply to 6.1-stable tree
Subsystems (3)
Sasha Levin
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Thanks,
Sasha
------------------ original commit in Linus's tree ------------------
From 54aaa3b387c2f580a99dc86a9cc2eb6dfaf599a7 Mon Sep 17 00:00:00 2001
From: Prashanth K <[email protected]>
Date: Wed, 4 Feb 2026 11:11:55 +0530
Subject: [PATCH] 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.
--- drivers/usb/dwc3/core.c | 19 ++++++++++++++++++- drivers/usb/dwc3/core.h | 4 ++++ drivers/usb/dwc3/gadget.c | 8 +++----- 3 files changed, 25 insertions(+), 6 deletions(-)
drivers/usb/dwc3/core.c +18 -1
@@ -2155,6 +2155,20 @@ static int dwc3_get_num_ports(struct dwc3 *dwc)return 0 ; } +static void dwc3_vbus_draw_work (struct work_struct *work) +{ + struct dwc3 *dwc = container_of(work, struct dwc3, vbus_draw_work); +union power_supply_propval val = {0 }; +int ret; + + val.intval =1000 * (dwc->current_limit); + ret =power_supply_set_property (dwc->usb_psy,POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT , &val); + +if (ret <0 ) +dev_dbg (dwc->dev,"Error (%d) setting vbus draw (%d mA)\n" , + ret, dwc->current_limit); +} +static struct power_supply *dwc3_get_usb_power_supply (struct dwc3 *dwc) {struct power_supply *usb_psy;
@@ -2169,6 +2183,7 @@ static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)if (!usb_psy)return ERR_PTR (-EPROBE_DEFER ); +INIT_WORK (&dwc->vbus_draw_work, dwc3_vbus_draw_work);return usb_psy; }
@@ -2395,8 +2410,10 @@ void dwc3_core_remove(struct dwc3 *dwc)dwc3_free_event_buffers (dwc); -if (dwc->usb_psy) +if (dwc->usb_psy) { +cancel_work_sync (&dwc->vbus_draw_work);power_supply_put (dwc->usb_psy); + } }EXPORT_SYMBOL_GPL (dwc3_core_remove);
drivers/usb/dwc3/core.h +4 -0
@@ -1058,6 +1058,8 @@ struct dwc3_glue_ops {* @role_switch_default_mode: default operation mode of controller while * usb role is USB_ROLE_NONE. * @usb_psy: pointer to power supply interface. +* @vbus_draw_work: Work to set the vbus drawing limit +* @current_limit: How much current to draw from vbus, in milliAmperes. * @usb2_phy: pointer to USB2 PHY * @usb3_phy: pointer to USB3 PHY * @usb2_generic_phy: pointer to array of USB2 PHYs
@@ -1244,6 +1246,8 @@ struct dwc3 {enum usb_dr_mode role_switch_default_mode;struct power_supply *usb_psy; +struct work_struct vbus_draw_work; +unsigned int current_limit;u32 fladj;u32 ref_clk_per;
drivers/usb/dwc3/gadget.c +3 -5
@@ -3124,8 +3124,6 @@ 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); -union power_supply_propval val = {0 }; -int ret;if (dwc->usb2_phy)return usb_phy_set_power (dwc->usb2_phy, mA);
@@ -3133,10 +3131,10 @@ static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA)if (!dwc->usb_psy)return -EOPNOTSUPP ; - val.intval =1000 * mA; - ret =power_supply_set_property (dwc->usb_psy,POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT , &val); + dwc->current_limit = mA; +schedule_work (&dwc->vbus_draw_work); -return ret; +return 0 ; }/**
Signature · 1 line
2.51.0