usb: common: usb-conn-gpio: manage connector ID with devres
PATCH 1/1 usb: common: usb-conn-gpio: manage connector ID with devres
usb_conn_psy_register() allocates a connector ID, but usb_conn_probe() does not release it if a later GPIO-to-IRQ conversion or IRQ request fails. The failed probe therefore leaks the allocated ID.
Manage the ID with a devm action registered before the power supply. This also makes the ID available only after the power supply has been unregistered during teardown, avoiding premature reuse of its name.
Fixes d4e5b10c5562 ("usb: common: usb-conn-gpio: use a unique name for usb connector device")
Reported-by Changyul Lee <[email protected]>
Assisted-by LLM
Signed-off-by Sang-Hoon Choi <[email protected]>
---
Compile-tested the affected object with x86_64 allmodconfig
and W=1 (GCC 13.3.0). Base: mainline 3b7cab693ba2bab63774bf5b988e8a61b2ef0f32. No hardware testing or runtime failure reproduction was performed.
drivers/usb/common/usb-conn-gpio.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
drivers/usb/common/usb-conn-gpio.c +14 -9
@@ -157,6 +157,13 @@ static int usb_charger_get_property(struct power_supply *psy,return 0 ; } +static void usb_conn_ida_free (void *data) +{ +struct usb_conn_info *info = data; + +ida_free (&usb_conn_ida, info->conn_id); +} +static int usb_conn_psy_register (struct usb_conn_info *info) {struct device *dev = info->dev;
@@ -164,17 +171,20 @@ static int usb_conn_psy_register(struct usb_conn_info *info)struct power_supply_config cfg = { .fwnode =dev_fwnode (dev), }; +int ret; info->conn_id =ida_alloc (&usb_conn_ida,GFP_KERNEL );if (info->conn_id <0 )return info->conn_id; + ret =devm_add_action_or_reset (dev, usb_conn_ida_free, info); +if (ret) +return ret; + desc->name =devm_kasprintf (dev,GFP_KERNEL ,"usb-charger-%d" , info->conn_id); -if (!desc->name) { -ida_free (&usb_conn_ida, info->conn_id); +if (!desc->name)return -ENOMEM ; - } desc->properties = usb_charger_properties; desc->num_properties =ARRAY_SIZE (usb_charger_properties);
@@ -183,10 +193,8 @@ static int usb_conn_psy_register(struct usb_conn_info *info) cfg.drv_data = info; info->charger =devm_power_supply_register (dev, desc, &cfg); -if (IS_ERR (info->charger)) { +if (IS_ERR (info->charger))dev_err (dev,"Unable to register charger %d\n" , info->conn_id); -ida_free (&usb_conn_ida, info->conn_id); - }return PTR_ERR_OR_ZERO (info->charger); }
@@ -294,9 +302,6 @@ static void usb_conn_remove(struct platform_device *pdev)cancel_delayed_work_sync (&info->dw_det); -if (info->charger) -ida_free (&usb_conn_ida, info->conn_id); -if (info->last_role ==USB_ROLE_HOST && info->vbus)regulator_disable (info->vbus);