diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index 44f28a114c2b..f4a851713cf1 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -592,7 +592,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
 	struct usb_bus *bus;
 	ssize_t ret, total_written = 0;
 	loff_t skip_bytes = *ppos;
-	int id;
+	unsigned long id;
 
 	if (*ppos < 0)
 		return -EINVAL;
@@ -601,9 +601,8 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
 	if (!access_ok(buf, nbytes))
 		return -EFAULT;
 
-	mutex_lock(&usb_bus_idr_lock);
 	/* print devices for all busses */
-	idr_for_each_entry(&usb_bus_idr, bus, id) {
+	xa_for_each(&usb_busses, id, bus) {
 		/* recurse through all children of the root hub */
 		if (!bus_to_hcd(bus)->rh_registered)
 			continue;
@@ -611,13 +610,10 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
 		ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos,
 				      bus->root_hub, bus, 0, 0, 0);
 		usb_unlock_device(bus->root_hub);
-		if (ret < 0) {
-			mutex_unlock(&usb_bus_idr_lock);
+		if (ret < 0)
 			return ret;
-		}
 		total_written += ret;
 	}
-	mutex_unlock(&usb_bus_idr_lock);
 	return total_written;
 }
 
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 3189181bb628..dac70d27abc7 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -79,15 +79,11 @@ unsigned long usb_hcds_loaded;
 EXPORT_SYMBOL_GPL(usb_hcds_loaded);
 
 /* host controllers we manage */
-DEFINE_IDR (usb_bus_idr);
-EXPORT_SYMBOL_GPL (usb_bus_idr);
+DEFINE_XARRAY_ALLOC1(usb_busses);
+EXPORT_SYMBOL_GPL(usb_busses);
 
 /* used when allocating bus numbers */
-#define USB_MAXBUS		64
-
-/* used when updating list of hcds */
-DEFINE_MUTEX(usb_bus_idr_lock);	/* exported only for usbfs */
-EXPORT_SYMBOL_GPL (usb_bus_idr_lock);
+#define USB_BUS_LIMIT		XA_LIMIT(0, 63)
 
 /* used for controlling access to virtual root hubs */
 static DEFINE_SPINLOCK(hcd_root_hub_lock);
@@ -1010,27 +1006,20 @@ static void usb_bus_init (struct usb_bus *bus)
  */
 static int usb_register_bus(struct usb_bus *bus)
 {
-	int result = -E2BIG;
-	int busnum;
+	int err;
 
-	mutex_lock(&usb_bus_idr_lock);
-	busnum = idr_alloc(&usb_bus_idr, bus, 1, USB_MAXBUS, GFP_KERNEL);
-	if (busnum < 0) {
+	err = xa_alloc(&usb_busses, &bus->busnum, bus, USB_BUS_LIMIT,
+			GFP_KERNEL);
+	if (err < 0) {
 		pr_err("%s: failed to get bus number\n", usbcore_name);
-		goto error_find_busnum;
+		return -E2BIG;
 	}
-	bus->busnum = busnum;
-	mutex_unlock(&usb_bus_idr_lock);
 
 	usb_notify_add_bus(bus);
 
 	dev_info (bus->controller, "new USB bus registered, assigned bus "
 		  "number %d\n", bus->busnum);
 	return 0;
-
-error_find_busnum:
-	mutex_unlock(&usb_bus_idr_lock);
-	return result;
 }
 
 /**
@@ -1050,9 +1039,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
 	 * controller code, as well as having it call this when cleaning
 	 * itself up
 	 */
-	mutex_lock(&usb_bus_idr_lock);
-	idr_remove(&usb_bus_idr, bus->busnum);
-	mutex_unlock(&usb_bus_idr_lock);
+	xa_erase(&usb_busses, bus->busnum);
 
 	usb_notify_remove_bus(bus);
 }
@@ -1080,12 +1067,9 @@ static int register_root_hub(struct usb_hcd *hcd)
 	set_bit (devnum, usb_dev->bus->devmap.devicemap);
 	usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
 
-	mutex_lock(&usb_bus_idr_lock);
-
 	usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
 	retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
 	if (retval != sizeof usb_dev->descriptor) {
-		mutex_unlock(&usb_bus_idr_lock);
 		dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
 				dev_name(&usb_dev->dev), retval);
 		return (retval < 0) ? retval : -EMSGSIZE;
@@ -1096,7 +1080,6 @@ static int register_root_hub(struct usb_hcd *hcd)
 		if (!retval) {
 			usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev);
 		} else if (usb_dev->speed >= USB_SPEED_SUPER) {
-			mutex_unlock(&usb_bus_idr_lock);
 			dev_dbg(parent_dev, "can't read %s bos descriptor %d\n",
 					dev_name(&usb_dev->dev), retval);
 			return retval;
@@ -1116,7 +1099,6 @@ static int register_root_hub(struct usb_hcd *hcd)
 		if (HCD_DEAD(hcd))
 			usb_hc_died (hcd);	/* This time clean up */
 	}
-	mutex_unlock(&usb_bus_idr_lock);
 
 	return retval;
 }
@@ -2905,9 +2887,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 #ifdef CONFIG_PM
 	cancel_work_sync(&hcd->wakeup_work);
 #endif
-	mutex_lock(&usb_bus_idr_lock);
 	usb_disconnect(&rhdev);		/* Sets rhdev to NULL */
-	mutex_unlock(&usb_bus_idr_lock);
 err_register_root_hub:
 	hcd->rh_pollable = 0;
 	clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
@@ -2966,9 +2946,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 	cancel_work_sync(&hcd->wakeup_work);
 #endif
 
-	mutex_lock(&usb_bus_idr_lock);
 	usb_disconnect(&rhdev);		/* Sets rhdev to NULL */
-	mutex_unlock(&usb_bus_idr_lock);
 
 	/*
 	 * tasklet_kill() isn't needed here because:
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 7fcb9f782931..b41090a80df0 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1274,7 +1274,6 @@ static void __exit usb_exit(void)
 	bus_unregister(&usb_bus_type);
 	usb_acpi_unregister();
 	usb_debugfs_cleanup();
-	idr_destroy(&usb_bus_idr);
 }
 
 subsys_initcall(usb_init);
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 42668aeca57c..4f9c6af00548 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2093,13 +2093,11 @@ static void r8a66597_check_detect_child(struct r8a66597 *r8a66597,
 
 	memset(now_map, 0, sizeof(now_map));
 
-	mutex_lock(&usb_bus_idr_lock);
-	bus = idr_find(&usb_bus_idr, hcd->self.busnum);
+	bus = xa_load(&usb_busses, hcd->self.busnum);
 	if (bus && bus->root_hub) {
 		collect_usb_address_map(bus->root_hub, now_map);
 		update_usb_address_map(r8a66597, bus->root_hub, now_map);
 	}
-	mutex_unlock(&usb_bus_idr_lock);
 }
 
 static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf)
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index 9812d102a005..3d7b35559d15 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -350,7 +350,8 @@ struct mon_bus *mon_bus_lookup(unsigned int num)
 static int __init mon_init(void)
 {
 	struct usb_bus *ubus;
-	int rc, id;
+	unsigned long id;
+	int rc;
 
 	if ((rc = mon_text_init()) != 0)
 		goto err_text;
@@ -366,11 +367,9 @@ static int __init mon_init(void)
 	}
 	// MOD_INC_USE_COUNT(which_module?);
 
-	mutex_lock(&usb_bus_idr_lock);
-	idr_for_each_entry(&usb_bus_idr, ubus, id)
+	xa_for_each(&usb_busses, id, ubus)
 		mon_bus_init(ubus);
 	usb_register_notify(&mon_nb);
-	mutex_unlock(&usb_bus_idr_lock);
 	return 0;
 
 err_reg:
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 695931b03684..929e11a91b47 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -644,8 +644,7 @@ extern void usb_set_device_state(struct usb_device *udev,
 
 /* exported only within usbcore */
 
-extern struct idr usb_bus_idr;
-extern struct mutex usb_bus_idr_lock;
+extern struct xarray usb_busses;
 extern wait_queue_head_t usb_kill_urb_queue;
 
 
