Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: common: usb-conn-gpio: use a unique name for usb connector device

The current implementation of the usb-conn-gpio driver uses a fixed
"usb-charger" name for all USB connector devices. This causes conflicts
in the power supply subsystem when multiple USB connectors are present,
as duplicate names are not allowed.

Use IDA to manage unique IDs for naming usb connectors (e.g.,
usb-charger-0, usb-charger-1).

Signed-off-by: Chance Yang <chance.yang@kneron.us>
Link: https://lore.kernel.org/r/20250411-work-next-v3-1-7cd9aa80190c@kneron.us
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Chance Yang and committed by
Greg Kroah-Hartman
d4e5b10c ffb34a60

+22 -3
+22 -3
drivers/usb/common/usb-conn-gpio.c
··· 21 21 #include <linux/regulator/consumer.h> 22 22 #include <linux/string_choices.h> 23 23 #include <linux/usb/role.h> 24 + #include <linux/idr.h> 25 + 26 + static DEFINE_IDA(usb_conn_ida); 24 27 25 28 #define USB_GPIO_DEB_MS 20 /* ms */ 26 29 #define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ ··· 33 30 34 31 struct usb_conn_info { 35 32 struct device *dev; 33 + int conn_id; /* store the IDA-allocated ID */ 36 34 struct usb_role_switch *role_sw; 37 35 enum usb_role last_role; 38 36 struct regulator *vbus; ··· 165 161 .fwnode = dev_fwnode(dev), 166 162 }; 167 163 168 - desc->name = "usb-charger"; 164 + info->conn_id = ida_alloc(&usb_conn_ida, GFP_KERNEL); 165 + if (info->conn_id < 0) 166 + return info->conn_id; 167 + 168 + desc->name = devm_kasprintf(dev, GFP_KERNEL, "usb-charger-%d", 169 + info->conn_id); 170 + if (!desc->name) { 171 + ida_free(&usb_conn_ida, info->conn_id); 172 + return -ENOMEM; 173 + } 174 + 169 175 desc->properties = usb_charger_properties; 170 176 desc->num_properties = ARRAY_SIZE(usb_charger_properties); 171 177 desc->get_property = usb_charger_get_property; ··· 183 169 cfg.drv_data = info; 184 170 185 171 info->charger = devm_power_supply_register(dev, desc, &cfg); 186 - if (IS_ERR(info->charger)) 187 - dev_err(dev, "Unable to register charger\n"); 172 + if (IS_ERR(info->charger)) { 173 + dev_err(dev, "Unable to register charger %d\n", info->conn_id); 174 + ida_free(&usb_conn_ida, info->conn_id); 175 + } 188 176 189 177 return PTR_ERR_OR_ZERO(info->charger); 190 178 } ··· 293 277 struct usb_conn_info *info = platform_get_drvdata(pdev); 294 278 295 279 cancel_delayed_work_sync(&info->dw_det); 280 + 281 + if (info->charger) 282 + ida_free(&usb_conn_ida, info->conn_id); 296 283 297 284 if (info->last_role == USB_ROLE_HOST && info->vbus) 298 285 regulator_disable(info->vbus);