diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index f9f47c1143bf..b84efae26e15 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -417,13 +417,9 @@ EXPORT_SYMBOL_GPL(usb_of_get_companion_dev);
 struct dentry *usb_debug_root;
 EXPORT_SYMBOL_GPL(usb_debug_root);
 
-spinlock_t usb_dynids_lock;
-EXPORT_SYMBOL_GPL(usb_dynids_lock);
-
 static int __init usb_common_init(void)
 {
 	usb_debug_root = debugfs_create_dir("usb", NULL);
-	spin_lock_init(&usb_dynids_lock);
 	ledtrig_usb_init();
 	return 0;
 }
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 3f69b32222f3..8bba102de39f 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -34,17 +34,76 @@
 
 #include "usb.h"
 
+static struct list_head usb_dynids;
+static spinlock_t usb_dynids_lock;
+
+struct usb_dynids {
+	struct list_head node;
+	const struct device_driver *driver;
+	struct list_head list;
+};
+
+struct usb_dynid {
+	struct list_head node;
+	struct usb_device_id id;
+};
+
+void usb_dynids_init(void)
+{
+	spin_lock_init(&usb_dynids_lock);
+	INIT_LIST_HEAD(&usb_dynids);
+}
+
+static struct usb_dynids *usb_find_dynids(const struct device_driver *driver)
+{
+	struct usb_dynids *u;
+
+	/* Loop through the list to find if this driver has an id list already */
+	guard(spinlock)(&usb_dynids_lock);
+	list_for_each_entry(u, &usb_dynids, node) {
+		if (u->driver == driver)
+			return u;
+	}
+	return NULL;
+}
+
+static int store_id(const struct device_driver *driver, const struct usb_device_id *id)
+{
+	struct usb_dynids *u;
+	struct usb_dynid *usb_dynid;
+
+	u = usb_find_dynids(driver);
+	if (!u) {
+		/* This driver has not stored any ids yet, so make a new entry for it */
+		u = kmalloc(sizeof(*u), GFP_KERNEL);
+		if (!u)
+			return -ENOMEM;
+		u->driver = driver;
+		INIT_LIST_HEAD(&u->list);
+		guard(spinlock)(&usb_dynids_lock);
+		list_add_tail(&u->node, &usb_dynids);
+	}
+
+	/* Allocate a new entry and add it to the list of driver ids for this driver */
+	usb_dynid = kmalloc(sizeof(*usb_dynid), GFP_KERNEL);
+	if (!usb_dynid)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&usb_dynid->node);
+	memcpy(&usb_dynid->id, id, sizeof(*id));
+	list_add_tail(&usb_dynid->node, &u->list);
+	return 0;
+}
 
 /*
  * Adds a new dynamic USBdevice ID to this driver,
  * and cause the driver to probe for all devices again.
  */
-ssize_t usb_store_new_id(struct usb_dynids *dynids,
+ssize_t usb_store_new_id(struct device_driver *driver,
 			 const struct usb_device_id *id_table,
-			 struct device_driver *driver,
 			 const char *buf, size_t count)
 {
-	struct usb_dynid *dynid;
+	struct usb_device_id new_id = {};
 	u32 idVendor = 0;
 	u32 idProduct = 0;
 	unsigned int bInterfaceClass = 0;
@@ -57,22 +116,17 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
 	if (fields < 2)
 		return -EINVAL;
 
-	dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
-	if (!dynid)
-		return -ENOMEM;
-
-	INIT_LIST_HEAD(&dynid->node);
-	dynid->id.idVendor = idVendor;
-	dynid->id.idProduct = idProduct;
-	dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+	new_id.idVendor = idVendor;
+	new_id.idProduct = idProduct;
+	new_id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
 	if (fields > 2 && bInterfaceClass) {
 		if (bInterfaceClass > 255) {
 			retval = -EINVAL;
 			goto fail;
 		}
 
-		dynid->id.bInterfaceClass = (u8)bInterfaceClass;
-		dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
+		new_id.bInterfaceClass = (u8)bInterfaceClass;
+		new_id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
 	}
 
 	if (fields > 4) {
@@ -88,16 +142,16 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
 				break;
 
 		if (id->match_flags) {
-			dynid->id.driver_info = id->driver_info;
+			new_id.driver_info = id->driver_info;
 		} else {
 			retval = -ENODEV;
 			goto fail;
 		}
 	}
 
-	spin_lock(&usb_dynids_lock);
-	list_add_tail(&dynid->node, &dynids->list);
-	spin_unlock(&usb_dynids_lock);
+	retval = store_id(driver, &new_id);
+	if (retval)
+		return retval;
 
 	retval = driver_attach(driver);
 
@@ -106,16 +160,20 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
 	return count;
 
 fail:
-	kfree(dynid);
 	return retval;
 }
 EXPORT_SYMBOL_GPL(usb_store_new_id);
 
-ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf)
+ssize_t usb_show_dynids(const struct device_driver *driver, char *buf)
 {
+	struct usb_dynids *dynids;
 	struct usb_dynid *dynid;
 	size_t count = 0;
 
+	dynids = usb_find_dynids(driver);
+	if (!dynids)
+		return 0;
+
 	list_for_each_entry(dynid, &dynids->list, node)
 		if (dynid->id.bInterfaceClass != 0)
 			count += scnprintf(&buf[count], PAGE_SIZE - count, "%04x %04x %02x\n",
@@ -130,9 +188,7 @@ EXPORT_SYMBOL_GPL(usb_show_dynids);
 
 static ssize_t new_id_show(struct device_driver *driver, char *buf)
 {
-	struct usb_driver *usb_drv = to_usb_driver(driver);
-
-	return usb_show_dynids(&usb_drv->dynids, buf);
+	return usb_show_dynids(driver, buf);
 }
 
 static ssize_t new_id_store(struct device_driver *driver,
@@ -140,7 +196,7 @@ static ssize_t new_id_store(struct device_driver *driver,
 {
 	struct usb_driver *usb_drv = to_usb_driver(driver);
 
-	return usb_store_new_id(&usb_drv->dynids, usb_drv->id_table, driver, buf, count);
+	return usb_store_new_id(driver, usb_drv->id_table, buf, count);
 }
 static DRIVER_ATTR_RW(new_id);
 
@@ -150,8 +206,8 @@ static DRIVER_ATTR_RW(new_id);
 static ssize_t remove_id_store(struct device_driver *driver, const char *buf,
 			       size_t count)
 {
+	struct usb_dynids *dynids;
 	struct usb_dynid *dynid, *n;
-	struct usb_driver *usb_driver = to_usb_driver(driver);
 	u32 idVendor;
 	u32 idProduct;
 	int fields;
@@ -160,8 +216,12 @@ static ssize_t remove_id_store(struct device_driver *driver, const char *buf,
 	if (fields < 2)
 		return -EINVAL;
 
+	dynids = usb_find_dynids(driver);
+	if (!dynids)
+		return count;
+
 	guard(spinlock)(&usb_dynids_lock);
-	list_for_each_entry_safe(dynid, n, &usb_driver->dynids.list, node) {
+	list_for_each_entry_safe(dynid, n, &dynids->list, node) {
 		struct usb_device_id *id = &dynid->id;
 
 		if ((id->idVendor == idVendor) &&
@@ -215,30 +275,44 @@ static void usb_remove_newid_files(struct usb_driver *usb_drv)
 	}
 }
 
-static void usb_free_dynids(struct usb_driver *usb_drv)
+void usb_free_dynids(const struct device_driver *drv)
 {
+	struct usb_dynids *dynids;
 	struct usb_dynid *dynid, *n;
 
+	dynids = usb_find_dynids(drv);
+	if (!dynids)
+		return;
+
 	guard(spinlock)(&usb_dynids_lock);
-	list_for_each_entry_safe(dynid, n, &usb_drv->dynids.list, node) {
+	list_for_each_entry_safe(dynid, n, &dynids->list, node) {
 		list_del(&dynid->node);
 		kfree(dynid);
 	}
+	list_del(&dynids->node);
+	kfree(dynids);
 }
+EXPORT_SYMBOL_GPL(usb_free_dynids);
 
-static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
-							const struct usb_driver *drv)
+const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
+						 const struct device_driver *driver)
 {
+	struct usb_dynids *dynids;
 	struct usb_dynid *dynid;
 
+	dynids = usb_find_dynids(driver);
+	if (!dynids)
+		return NULL;
+
 	guard(spinlock)(&usb_dynids_lock);
-	list_for_each_entry(dynid, &drv->dynids.list, node) {
+	list_for_each_entry(dynid, &dynids->list, node) {
 		if (usb_match_one_id(intf, &dynid->id)) {
 			return &dynid->id;
 		}
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(usb_match_dynamic_id);
 
 
 /* called from driver core with dev locked */
@@ -339,7 +413,7 @@ static int usb_probe_interface(struct device *dev)
 		return error;
 	}
 
-	id = usb_match_dynamic_id(intf, driver);
+	id = usb_match_dynamic_id(intf, &driver->driver);
 	if (!id)
 		id = usb_match_id(intf, driver->id_table);
 	if (!id)
@@ -890,7 +964,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv)
 		if (id)
 			return 1;
 
-		id = usb_match_dynamic_id(intf, usb_drv);
+		id = usb_match_dynamic_id(intf, &usb_drv->driver);
 		if (id)
 			return 1;
 	}
@@ -1058,7 +1132,6 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
 	new_driver->driver.owner = owner;
 	new_driver->driver.mod_name = mod_name;
 	new_driver->driver.dev_groups = new_driver->dev_groups;
-	INIT_LIST_HEAD(&new_driver->dynids.list);
 
 	retval = driver_register(&new_driver->driver);
 	if (retval)
@@ -1100,8 +1173,8 @@ void usb_deregister(struct usb_driver *driver)
 			usbcore_name, driver->name);
 
 	usb_remove_newid_files(driver);
+	usb_free_dynids(&driver->driver);
 	driver_unregister(&driver->driver);
-	usb_free_dynids(driver);
 }
 EXPORT_SYMBOL_GPL(usb_deregister);
 
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index a0c432b14b20..6261696f40f0 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1078,6 +1078,7 @@ static int __init usb_init(void)
 	usb_init_pool_max();
 
 	usb_debugfs_init();
+	usb_dynids_init();
 
 	usb_acpi_register();
 	retval = bus_register(&usb_bus_type);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index a9b37aeb515b..b904d54133ea 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -89,6 +89,7 @@ extern int usb_major_init(void);
 extern void usb_major_cleanup(void);
 extern int usb_device_supports_lpm(struct usb_device *udev);
 extern int usb_port_disable(struct usb_device *udev);
+void usb_dynids_init(void);
 
 #ifdef	CONFIG_PM
 
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index c1af1eb6d571..0d45e8122068 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -107,22 +107,18 @@ static ssize_t new_id_store(struct device_driver *driver,
 			    const char *buf, size_t count)
 {
 	struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver);
-	ssize_t retval = usb_store_new_id(&usb_drv->dynids, usb_drv->id_table,
-					 driver, buf, count);
+	ssize_t retval = usb_store_new_id(driver, usb_drv->id_table, buf, count);
 
 	if (retval >= 0 && usb_drv->usb_driver != NULL)
-		retval = usb_store_new_id(&usb_drv->usb_driver->dynids,
+		retval = usb_store_new_id(&usb_drv->usb_driver->driver,
 					  usb_drv->usb_driver->id_table,
-					  &usb_drv->usb_driver->driver,
 					  buf, count);
 	return retval;
 }
 
 static ssize_t new_id_show(struct device_driver *driver, char *buf)
 {
-	struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver);
-
-	return usb_show_dynids(&usb_drv->dynids, buf);
+	return usb_show_dynids(driver, buf);
 }
 static DRIVER_ATTR_RW(new_id);
 
@@ -132,17 +128,6 @@ static struct attribute *usb_serial_drv_attrs[] = {
 };
 ATTRIBUTE_GROUPS(usb_serial_drv);
 
-static void free_dynids(struct usb_serial_driver *drv)
-{
-	struct usb_dynid *dynid, *n;
-
-	guard(spinlock)(&usb_dynids_lock);
-	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
-		list_del(&dynid->node);
-		kfree(dynid);
-	}
-}
-
 const struct bus_type usb_serial_bus_type = {
 	.name =		"usb-serial",
 	.match =	usb_serial_device_match,
@@ -156,7 +141,6 @@ int usb_serial_bus_register(struct usb_serial_driver *driver)
 	int retval;
 
 	driver->driver.bus = &usb_serial_bus_type;
-	INIT_LIST_HEAD(&driver->dynids.list);
 
 	retval = driver_register(&driver->driver);
 
@@ -165,7 +149,7 @@ int usb_serial_bus_register(struct usb_serial_driver *driver)
 
 void usb_serial_bus_deregister(struct usb_serial_driver *driver)
 {
-	free_dynids(driver);
+	usb_free_dynids(&driver->driver);
 	driver_unregister(&driver->driver);
 }
 
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index ad947efcd80b..c05138c190e5 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -701,20 +701,6 @@ static struct usb_serial *create_serial(struct usb_device *dev,
 	return serial;
 }
 
-static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
-					    struct usb_serial_driver *drv)
-{
-	struct usb_dynid *dynid;
-
-	guard(spinlock)(&usb_dynids_lock);
-	list_for_each_entry(dynid, &drv->dynids.list, node) {
-		if (usb_match_one_id(intf, &dynid->id)) {
-			return &dynid->id;
-		}
-	}
-	return NULL;
-}
-
 static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
 						struct usb_interface *intf)
 {
@@ -725,7 +711,7 @@ static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
 		dev_dbg(&intf->dev, "static descriptor matches\n");
 		goto exit;
 	}
-	id = match_dynamic_id(intf, drv);
+	id = usb_match_dynamic_id(intf, &drv->driver);
 	if (id)
 		dev_dbg(&intf->dev, "dynamic descriptor matches\n");
 exit:
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 10fc4db764b5..735f947c879f 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1121,22 +1121,13 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size)
 /* ----------------------------------------------------------------------- */
 
 /* Stuff for dynamic usb ids */
-extern spinlock_t usb_dynids_lock;
-struct usb_dynids {
-	struct list_head list;
-};
-
-struct usb_dynid {
-	struct list_head node;
-	struct usb_device_id id;
-};
-
-extern ssize_t usb_store_new_id(struct usb_dynids *dynids,
-				const struct usb_device_id *id_table,
-				struct device_driver *driver,
-				const char *buf, size_t count);
-
-extern ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf);
+ssize_t usb_store_new_id(struct device_driver *driver,
+			 const struct usb_device_id *id_table,
+			 const char *buf, size_t count);
+ssize_t usb_show_dynids(const struct device_driver *driver, char *buf);
+const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
+						 const struct device_driver *driver);
+void usb_free_dynids(const struct device_driver *driver);
 
 /**
  * struct usb_driver - identifies USB interface driver to usbcore
@@ -1225,7 +1216,6 @@ struct usb_driver {
 	const struct usb_device_id *id_table;
 	const struct attribute_group **dev_groups;
 
-	struct usb_dynids dynids;
 	struct device_driver driver;
 	unsigned int no_dynamic_id:1;
 	unsigned int supports_autosuspend:1;
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 1a0a4dc87980..3e8c8c1e3ac6 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -237,7 +237,6 @@ struct usb_serial_driver {
 	struct list_head	driver_list;
 	struct device_driver	driver;
 	struct usb_driver	*usb_driver;
-	struct usb_dynids	dynids;
 
 	unsigned char		num_ports;
 
