diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 764d176e9735..b926e9dbdbb9 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1298,6 +1298,7 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
 	 * force_poll_sync changes.
 	 */
 	switch (urb->dev->speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
 	case USB_SPEED_SUPER_PLUS:
 	case USB_SPEED_SUPER:	/* units are 125us */
 		data->intr_interval = usecs_to_jiffies(urb->interval * 125);
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 28dde08ec6c5..ede56f46881f 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1791,6 +1791,7 @@ u16 uvc_endpoint_max_bpi(struct usb_device *dev, struct usb_host_endpoint *ep)
 	switch (dev->speed) {
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
 	default:
 		psize = usb_endpoint_maxp(&ep->desc);
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0738baa5b82e..e993ca78df09 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -7066,6 +7066,7 @@ static void r8153_init(struct r8152 *tp)
 	switch (tp->udev->speed) {
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		tp->coalesce = COALESCE_SUPER;
 		break;
 	case USB_SPEED_HIGH:
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 2d14b0d78541..e9032c1cf66b 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -366,6 +366,7 @@ void usbnet_update_max_qlen(struct usbnet *dev)
 		break;
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		/*
 		 * Not take default 5ms qlen for super speed HC to
 		 * save memory, and iperf tests show 2.5ms qlen can
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 2178675ae1a4..43571daf3df0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -1427,14 +1427,19 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
 	devinfo->ifnum = desc->bInterfaceNumber;
 
-	if (usb->speed == USB_SPEED_SUPER_PLUS)
-		brcmf_dbg(USB, "Broadcom super speed plus USB WLAN interface detected\n");
-	else if (usb->speed == USB_SPEED_SUPER)
-		brcmf_dbg(USB, "Broadcom super speed USB WLAN interface detected\n");
-	else if (usb->speed == USB_SPEED_HIGH)
-		brcmf_dbg(USB, "Broadcom high speed USB WLAN interface detected\n");
-	else
-		brcmf_dbg(USB, "Broadcom full speed USB WLAN interface detected\n");
+	switch (usb->speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
+	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER:
+	case USB_SPEED_HIGH:
+		brcmf_dbg(USB, "Broadcom %s USB WLAN interface detected\n",
+			  usb_speed_string(usb->speed));
+		break;
+	default:
+		brcmf_dbg(USB, "Broadcom %s USB WLAN interface detected\n",
+			  usb_speed_string(USB_SPEED_FULL));
+		break;
+	}
 
 	ret = brcmf_usb_probe_cb(devinfo, id->driver_info);
 	if (ret)
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index a296b87dced1..2f6d7fee17bd 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -977,7 +977,7 @@ static int tegra_xusb_usb3_port_parse_dt(struct tegra_xusb_usb3_port *usb3)
 		maximum_speed =  usb_get_maximum_speed(&port->dev);
 		if (maximum_speed == USB_SPEED_SUPER)
 			usb3->disable_gen2 = true;
-		else if (maximum_speed == USB_SPEED_SUPER_PLUS)
+		else if (maximum_speed >= USB_SPEED_SUPER_PLUS)
 			usb3->disable_gen2 = false;
 		else
 			return -EINVAL;
diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c
index fff9ec9c391f..f755b947d7d8 100644
--- a/drivers/usb/cdns3/cdnsp-gadget.c
+++ b/drivers/usb/cdns3/cdnsp-gadget.c
@@ -1250,6 +1250,7 @@ static int cdnsp_run(struct cdnsp_device *pdev,
 	temp = readl(&pdev->port3x_regs->mode_addr);
 
 	switch (speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
 	case USB_SPEED_SUPER_PLUS:
 		temp |= CFG_3XPORT_SSP_SUPPORT;
 		break;
@@ -1745,6 +1746,7 @@ void cdnsp_irq_reset(struct cdnsp_device *pdev)
 	spin_lock(&pdev->lock);
 
 	switch (pdev->gadget.speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
 	case USB_SPEED_SUPER_PLUS:
 	case USB_SPEED_SUPER:
 		cdnsp_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
@@ -1873,6 +1875,7 @@ static int __cdnsp_gadget_init(struct cdns *cdns)
 	case USB_SPEED_HIGH:
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		break;
 	default:
 		dev_err(cdns->dev, "invalid speed parameter %d\n", max_speed);
diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c
index 97866bfb2da9..9cf3516eb9ce 100644
--- a/drivers/usb/cdns3/cdnsp-mem.c
+++ b/drivers/usb/cdns3/cdnsp-mem.c
@@ -736,6 +736,7 @@ int cdnsp_setup_addressable_priv_dev(struct cdnsp_device *pdev)
 	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1));
 
 	switch (pdev->gadget.speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
 	case USB_SPEED_SUPER_PLUS:
 		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SSP);
 		max_packets = MAX_PACKET(512);
@@ -833,8 +834,9 @@ static unsigned int cdnsp_get_endpoint_interval(struct usb_gadget *g,
 
 	switch (g->speed) {
 	case USB_SPEED_HIGH:
-	case USB_SPEED_SUPER_PLUS:
 	case USB_SPEED_SUPER:
+	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		if (usb_endpoint_xfer_int(pep->endpoint.desc) ||
 		    usb_endpoint_xfer_isoc(pep->endpoint.desc))
 			interval = cdnsp_parse_exponent_interval(g, pep);
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index b84efae26e15..41bd032fc139 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -67,22 +67,35 @@ const char *usb_otg_state_string(enum usb_otg_state state)
 EXPORT_SYMBOL_GPL(usb_otg_state_string);
 
 static const char *const speed_names[] = {
-	[USB_SPEED_UNKNOWN] = "UNKNOWN",
+	[USB_SPEED_UNKNOWN] = "unknown-speed",
 	[USB_SPEED_LOW] = "low-speed",
 	[USB_SPEED_FULL] = "full-speed",
 	[USB_SPEED_HIGH] = "high-speed",
 	[USB_SPEED_WIRELESS] = "wireless",
 	[USB_SPEED_SUPER] = "super-speed",
 	[USB_SPEED_SUPER_PLUS] = "super-speed-plus",
+	[USB_SPEED_SUPER_PLUS_BY2] = "super-speed-plus-by2",
 };
 
-static const char *const ssp_rate[] = {
-	[USB_SSP_GEN_UNKNOWN] = "UNKNOWN",
+static const char *const ssp_gen_names[] = {
+	[USB_SSP_GEN_UNKNOWN] = "super-speed-plus-gen-unknown",
 	[USB_SSP_GEN_2x1] = "super-speed-plus-gen2x1",
 	[USB_SSP_GEN_1x2] = "super-speed-plus-gen1x2",
 	[USB_SSP_GEN_2x2] = "super-speed-plus-gen2x2",
 };
 
+/* Mbps */
+static const char *const speed_values[] = {
+	[USB_SPEED_UNKNOWN] = "unknown-value",
+	[USB_SPEED_LOW] = "1.5",
+	[USB_SPEED_FULL] = "12",
+	[USB_SPEED_HIGH] = "480",
+	[USB_SPEED_WIRELESS] = "480",
+	[USB_SPEED_SUPER] = "5000",
+	[USB_SPEED_SUPER_PLUS] = "10000",
+	[USB_SPEED_SUPER_PLUS_BY2] = "20000",
+};
+
 /**
  * usb_speed_string() - Returns human readable-name of the speed.
  * @speed: The speed to return human-readable name for.  If it's not
@@ -97,6 +110,56 @@ const char *usb_speed_string(enum usb_device_speed speed)
 }
 EXPORT_SYMBOL_GPL(usb_speed_string);
 
+/**
+ * usb_speed_value() - Returns human readable speed value.
+ * @speed: The speed to return human-readable value for. If it's not
+ *   any of the speeds defined in usb_device_speed enum, value for
+ *   USB_SPEED_UNKNOWN will be returned.
+ */
+const char *usb_speed_value(enum usb_device_speed speed)
+{
+	if (speed < 0 || speed >= ARRAY_SIZE(speed_values))
+		speed = USB_SPEED_UNKNOWN;
+	return speed_values[speed];
+}
+EXPORT_SYMBOL_GPL(usb_speed_value);
+
+/**
+ * usb_ssp_gen_name() - Returns human readable-name of ssp generation.
+ * @gen: The ssp generation to return human-readable name for. If it's
+ *   not any of the values defined in usb_ssp_gen enum, name for
+ *   USB_SSP_GEN_UNKNOWN will be returned.
+ */
+const char *usb_ssp_gen_name(enum usb_ssp_gen gen)
+{
+	if (gen < 0 || gen >= ARRAY_SIZE(ssp_gen_names))
+		gen = USB_SSP_GEN_UNKNOWN;
+	return ssp_gen_names[gen];
+}
+EXPORT_SYMBOL_GPL(usb_ssp_gen_name);
+
+/**
+ * usb_speed_from_name() - Returns usb_device_speed enum from human
+ * readable name.
+ * @speed_name: The speed name to return usb_device_speed enum for,
+ *   which can be defined in speed_names or ssp_gen_names. USB_SPEED_UNKNOWN
+ *   will be returned if the name can't be recognized.
+ */
+enum usb_device_speed usb_speed_from_name(const char *speed_name)
+{
+	int ret;
+
+	ret = match_string(ssp_gen_names, ARRAY_SIZE(ssp_gen_names), speed_name);
+	if (ret == USB_SSP_GEN_2x2)
+		return USB_SPEED_SUPER_PLUS_BY2;
+	else if (ret > 0)
+		return USB_SPEED_SUPER_PLUS;
+
+	ret = match_string(speed_names, ARRAY_SIZE(speed_names), speed_name);
+	return (ret < 0) ? USB_SPEED_UNKNOWN : ret;
+}
+EXPORT_SYMBOL_GPL(usb_speed_from_name);
+
 /**
  * usb_get_maximum_speed - Get maximum requested speed for a given USB
  * controller.
@@ -114,25 +177,21 @@ enum usb_device_speed usb_get_maximum_speed(struct device *dev)
 	if (ret < 0)
 		return USB_SPEED_UNKNOWN;
 
-	ret = match_string(ssp_rate, ARRAY_SIZE(ssp_rate), maximum_speed);
-	if (ret > 0)
-		return USB_SPEED_SUPER_PLUS;
+	return usb_speed_from_name(maximum_speed);
 
-	ret = match_string(speed_names, ARRAY_SIZE(speed_names), maximum_speed);
-	return (ret < 0) ? USB_SPEED_UNKNOWN : ret;
 }
 EXPORT_SYMBOL_GPL(usb_get_maximum_speed);
 
 /**
- * usb_get_maximum_ssp_rate - Get the signaling rate generation and lane count
+ * usb_get_maximum_ssp_gen - Get the SSP signaling generation and lane count
  *	of a SuperSpeed Plus capable device.
  * @dev: Pointer to the given USB controller device
  *
  * If the string from "maximum-speed" property is super-speed-plus-genXxY where
  * 'X' is the generation number and 'Y' is the number of lanes, then this
- * function returns the corresponding enum usb_ssp_rate.
+ * function returns the corresponding enum usb_ssp_gen.
  */
-enum usb_ssp_rate usb_get_maximum_ssp_rate(struct device *dev)
+enum usb_ssp_gen usb_get_maximum_ssp_gen(struct device *dev)
 {
 	const char *maximum_speed;
 	int ret;
@@ -141,10 +200,10 @@ enum usb_ssp_rate usb_get_maximum_ssp_rate(struct device *dev)
 	if (ret < 0)
 		return USB_SSP_GEN_UNKNOWN;
 
-	ret = match_string(ssp_rate, ARRAY_SIZE(ssp_rate), maximum_speed);
+	ret = match_string(ssp_gen_names, ARRAY_SIZE(ssp_gen_names), maximum_speed);
 	return (ret < 0) ? USB_SSP_GEN_UNKNOWN : ret;
 }
-EXPORT_SYMBOL_GPL(usb_get_maximum_ssp_rate);
+EXPORT_SYMBOL_GPL(usb_get_maximum_ssp_gen);
 
 /**
  * usb_state_string - Returns human readable name for the state.
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index b19e38d5fd10..71708ee7190c 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -323,6 +323,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
 	if (usb_endpoint_xfer_int(d)) {
 		i = 1;
 		switch (udev->speed) {
+		case USB_SPEED_SUPER_PLUS_BY2:
 		case USB_SPEED_SUPER_PLUS:
 		case USB_SPEED_SUPER:
 		case USB_SPEED_HIGH:
@@ -433,6 +434,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
 		break;
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		maxpacket_maxes = super_speed_maxpacket_maxes;
 		break;
 	}
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index a247da73f34d..62ab4dfa9a51 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -395,7 +395,8 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
 	int chix;
 	int ret, cnt = 0;
 	int parent_devnum = 0;
-	char *pages_start, *data_end, *speed;
+	char *pages_start, *data_end;
+	const char *speed;
 	unsigned int length;
 	ssize_t total_written = 0;
 	struct usb_device *childdev = NULL;
@@ -419,19 +420,16 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
 	 * plugged into the root hub has a parent of 0.
 	 */
 	switch (usbdev->speed) {
-	case USB_SPEED_LOW:
-		speed = "1.5"; break;
 	case USB_SPEED_UNKNOWN:		/* usb 1.1 root hub code */
-	case USB_SPEED_FULL:
 		speed = "12"; break;
+	case USB_SPEED_LOW:
+	case USB_SPEED_FULL:
 	case USB_SPEED_HIGH:
-		speed = "480"; break;
 	case USB_SPEED_SUPER:
-		speed = "5000"; break;
 	case USB_SPEED_SUPER_PLUS:
-		speed = "10000"; break;
+	case USB_SPEED_SUPER_PLUS_BY2:
 	default:
-		speed = "??";
+		speed = usb_speed_value(usbdev->speed); break;
 	}
 	data_end = pages_start + sprintf(pages_start, format_topo,
 			bus->busnum, level, parent_devnum,
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 12b6dfeaf658..315bb6887a06 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2865,7 +2865,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 
 	rhdev->rx_lanes = 1;
 	rhdev->tx_lanes = 1;
-	rhdev->ssp_rate = USB_SSP_GEN_UNKNOWN;
+	rhdev->ssp_gen = USB_SSP_GEN_UNKNOWN;
 
 	switch (hcd->speed) {
 	case HCD_USB11:
@@ -2880,11 +2880,11 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	case HCD_USB32:
 		rhdev->rx_lanes = 2;
 		rhdev->tx_lanes = 2;
-		rhdev->ssp_rate = USB_SSP_GEN_2x2;
-		rhdev->speed = USB_SPEED_SUPER_PLUS;
+		rhdev->ssp_gen = USB_SSP_GEN_2x2;
+		rhdev->speed = USB_SPEED_SUPER_PLUS_BY2;
 		break;
 	case HCD_USB31:
-		rhdev->ssp_rate = USB_SSP_GEN_2x1;
+		rhdev->ssp_gen = USB_SSP_GEN_2x1;
 		rhdev->speed = USB_SPEED_SUPER_PLUS;
 		break;
 	default:
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3c54b218301c..76eb864f939c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2693,16 +2693,16 @@ int usb_authorize_device(struct usb_device *usb_dev)
 }
 
 /**
- * get_port_ssp_rate - Match the extended port status to SSP rate
+ * get_port_ssp_gen - Match the extended port status to SSP generation
  * @hdev: The hub device
  * @ext_portstatus: extended port status
  *
  * Match the extended port status speed id to the SuperSpeed Plus sublink speed
  * capability attributes. Base on the number of connected lanes and speed,
- * return the corresponding enum usb_ssp_rate.
+ * return the corresponding enum usb_ssp_gen.
  */
-static enum usb_ssp_rate get_port_ssp_rate(struct usb_device *hdev,
-					   u32 ext_portstatus)
+static enum usb_ssp_gen get_port_ssp_gen(struct usb_device *hdev,
+					  u32 ext_portstatus)
 {
 	struct usb_ssp_cap_descriptor *ssp_cap = hdev->bos->ssp_cap;
 	u32 attr;
@@ -2913,13 +2913,15 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
 		/* extended portstatus Rx and Tx lane count are zero based */
 		udev->rx_lanes = USB_EXT_PORT_RX_LANES(ext_portstatus) + 1;
 		udev->tx_lanes = USB_EXT_PORT_TX_LANES(ext_portstatus) + 1;
-		udev->ssp_rate = get_port_ssp_rate(hub->hdev, ext_portstatus);
+		udev->ssp_gen = get_port_ssp_gen(hub->hdev, ext_portstatus);
 	} else {
 		udev->rx_lanes = 1;
 		udev->tx_lanes = 1;
-		udev->ssp_rate = USB_SSP_GEN_UNKNOWN;
+		udev->ssp_gen = USB_SSP_GEN_UNKNOWN;
 	}
-	if (udev->ssp_rate != USB_SSP_GEN_UNKNOWN)
+	if (udev->ssp_gen == USB_SSP_GEN_2x2)
+		udev->speed = USB_SPEED_SUPER_PLUS_BY2;
+	else if (udev->ssp_gen != USB_SSP_GEN_UNKNOWN)
 		udev->speed = USB_SPEED_SUPER_PLUS;
 	else if (hub_is_superspeed(hub->hdev))
 		udev->speed = USB_SPEED_SUPER;
@@ -4830,6 +4832,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
 		 * it's fixed size except for full speed devices.
 		 */
 		switch (udev->speed) {
+		case USB_SPEED_SUPER_PLUS_BY2:
 		case USB_SPEED_SUPER_PLUS:
 		case USB_SPEED_SUPER:
 			udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
@@ -4960,16 +4963,11 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
 		if (udev->speed >= USB_SPEED_SUPER) {
 			devnum = udev->devnum;
 			dev_info(&udev->dev,
-					"%s SuperSpeed%s%s USB device number %d using %s\n",
-					(udev->config) ? "reset" : "new",
-				 (udev->speed == USB_SPEED_SUPER_PLUS) ?
-						" Plus" : "",
-				 (udev->ssp_rate == USB_SSP_GEN_2x2) ?
-						" Gen 2x2" :
-				 (udev->ssp_rate == USB_SSP_GEN_2x1) ?
-						" Gen 2x1" :
-				 (udev->ssp_rate == USB_SSP_GEN_1x2) ?
-						" Gen 1x2" : "",
+				 "%s %s USB device number %d using %s\n",
+				 (udev->config) ? "reset" : "new",
+				 (udev->speed == USB_SPEED_SUPER) ?
+					usb_speed_string(USB_SPEED_SUPER) :
+					usb_ssp_gen_name(udev->ssp_gen),
 				 devnum, driver_name);
 		}
 
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 5d21718afb05..121c94fd3599 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -146,32 +146,21 @@ static ssize_t speed_show(struct device *dev, struct device_attribute *attr,
 			  char *buf)
 {
 	struct usb_device *udev;
-	char *speed;
+	const char *speed;
 
 	udev = to_usb_device(dev);
 
 	switch (udev->speed) {
-	case USB_SPEED_LOW:
-		speed = "1.5";
-		break;
 	case USB_SPEED_UNKNOWN:
+		speed = "12"; break;
+	case USB_SPEED_LOW:
 	case USB_SPEED_FULL:
-		speed = "12";
-		break;
 	case USB_SPEED_HIGH:
-		speed = "480";
-		break;
 	case USB_SPEED_SUPER:
-		speed = "5000";
-		break;
 	case USB_SPEED_SUPER_PLUS:
-		if (udev->ssp_rate == USB_SSP_GEN_2x2)
-			speed = "20000";
-		else
-			speed = "10000";
-		break;
+	case USB_SPEED_SUPER_PLUS_BY2:
 	default:
-		speed = "unknown";
+		speed = usb_speed_value(udev->speed); break;
 	}
 	return sysfs_emit(buf, "%s\n", speed);
 }
@@ -656,8 +645,7 @@ static int add_power_attributes(struct device *dev)
 		if (udev->usb2_hw_lpm_capable == 1)
 			rc = sysfs_merge_group(&dev->kobj,
 					&usb2_hardware_lpm_attr_group);
-		if ((udev->speed == USB_SPEED_SUPER ||
-		     udev->speed == USB_SPEED_SUPER_PLUS) &&
+		if (udev->speed >= USB_SPEED_SUPER &&
 				udev->lpm_capable == 1)
 			rc = sysfs_merge_group(&dev->kobj,
 					&usb3_hardware_lpm_attr_group);
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 7576920e2d5a..d90df1ca050c 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -459,7 +459,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 			max *= mult;
 		}
 
-		if (dev->speed == USB_SPEED_SUPER_PLUS &&
+		if (dev->speed >= USB_SPEED_SUPER_PLUS &&
 		    USB_SS_SSP_ISOC_COMP(ep->ss_ep_comp.bmAttributes)) {
 			struct usb_ssp_isoc_ep_comp_descriptor *isoc_ep_comp;
 
@@ -544,6 +544,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 
 		/* too big? */
 		switch (dev->speed) {
+		case USB_SPEED_SUPER_PLUS_BY2:
 		case USB_SPEED_SUPER_PLUS:
 		case USB_SPEED_SUPER:	/* units are 125us */
 			/* Handle up to 2^(16-1) microframes */
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 9c6bf054f15d..70ac85ad192d 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1408,7 +1408,7 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 	tx_fifo_resize_max_num = 6;
 
 	dwc->maximum_speed = usb_get_maximum_speed(dev);
-	dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev);
+	dwc->max_ssp_gen = usb_get_maximum_ssp_gen(dev);
 	dwc->dr_mode = usb_get_dr_mode(dev);
 	dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
 
@@ -1575,6 +1575,7 @@ static void dwc3_check_params(struct dwc3 *dwc)
 			dev_warn(dev, "UDC doesn't support Gen 1\n");
 		break;
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		if ((DWC3_IP_IS(DWC32) &&
 		     hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_DIS) ||
 		    (!DWC3_IP_IS(DWC32) &&
@@ -1613,8 +1614,8 @@ static void dwc3_check_params(struct dwc3 *dwc)
 	 * set the default to support dual-lane for DWC_usb32 and single-lane
 	 * for DWC_usb31 for super-speed-plus.
 	 */
-	if (dwc->maximum_speed == USB_SPEED_SUPER_PLUS) {
-		switch (dwc->max_ssp_rate) {
+	if (dwc->maximum_speed >= USB_SPEED_SUPER_PLUS) {
+		switch (dwc->max_ssp_gen) {
 		case USB_SSP_GEN_2x1:
 			if (hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_GEN1)
 				dev_warn(dev, "UDC only supports Gen 1\n");
@@ -1628,14 +1629,15 @@ static void dwc3_check_params(struct dwc3 *dwc)
 		default:
 			switch (hwparam_gen) {
 			case DWC3_GHWPARAMS3_SSPHY_IFC_GEN2:
-				if (DWC3_IP_IS(DWC32))
-					dwc->max_ssp_rate = USB_SSP_GEN_2x2;
-				else
-					dwc->max_ssp_rate = USB_SSP_GEN_2x1;
+				if (DWC3_IP_IS(DWC32)) {
+					dwc->max_ssp_gen = USB_SSP_GEN_2x2;
+					dwc->maximum_speed = USB_SPEED_SUPER_PLUS_BY2;
+				} else
+					dwc->max_ssp_gen = USB_SSP_GEN_2x1;
 				break;
 			case DWC3_GHWPARAMS3_SSPHY_IFC_GEN1:
 				if (DWC3_IP_IS(DWC32))
-					dwc->max_ssp_rate = USB_SSP_GEN_1x2;
+					dwc->max_ssp_gen = USB_SSP_GEN_1x2;
 				break;
 			}
 			break;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index a69ac67d89fe..414be70633df 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1194,8 +1194,8 @@ struct dwc3 {
 	u32			u1u2;
 	u32			maximum_speed;
 	u32			gadget_max_speed;
-	enum usb_ssp_rate	max_ssp_rate;
-	enum usb_ssp_rate	gadget_ssp_rate;
+	enum usb_ssp_gen	max_ssp_gen;
+	enum usb_ssp_gen	gadget_ssp_gen;
 
 	u32			ip;
 
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 858fe4c299b7..a9998ea731b8 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2498,23 +2498,23 @@ static void dwc3_stop_active_transfers(struct dwc3 *dwc)
 
 static void __dwc3_gadget_set_ssp_rate(struct dwc3 *dwc)
 {
-	enum usb_ssp_rate	ssp_rate = dwc->gadget_ssp_rate;
+	enum usb_ssp_gen	ssp_gen = dwc->gadget_ssp_gen;
 	u32			reg;
 
-	if (ssp_rate == USB_SSP_GEN_UNKNOWN)
-		ssp_rate = dwc->max_ssp_rate;
+	if (ssp_gen == USB_SSP_GEN_UNKNOWN)
+		ssp_gen = dwc->max_ssp_gen;
 
 	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
 	reg &= ~DWC3_DCFG_SPEED_MASK;
 	reg &= ~DWC3_DCFG_NUMLANES(~0);
 
-	if (ssp_rate == USB_SSP_GEN_1x2)
+	if (ssp_gen == USB_SSP_GEN_1x2)
 		reg |= DWC3_DCFG_SUPERSPEED;
-	else if (dwc->max_ssp_rate != USB_SSP_GEN_1x2)
+	else if (dwc->max_ssp_gen != USB_SSP_GEN_1x2)
 		reg |= DWC3_DCFG_SUPERSPEED_PLUS;
 
-	if (ssp_rate != USB_SSP_GEN_2x1 &&
-	    dwc->max_ssp_rate != USB_SSP_GEN_2x1)
+	if (ssp_gen != USB_SSP_GEN_2x1 &&
+	    dwc->max_ssp_gen != USB_SSP_GEN_2x1)
 		reg |= DWC3_DCFG_NUMLANES(1);
 
 	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
@@ -2529,7 +2529,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc)
 	if (speed == USB_SPEED_UNKNOWN || speed > dwc->maximum_speed)
 		speed = dwc->maximum_speed;
 
-	if (speed == USB_SPEED_SUPER_PLUS &&
+	if (speed >= USB_SPEED_SUPER_PLUS &&
 	    DWC3_IP_IS(DWC32)) {
 		__dwc3_gadget_set_ssp_rate(dwc);
 		return;
@@ -2566,6 +2566,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc)
 			reg |= DWC3_DCFG_SUPERSPEED;
 			break;
 		case USB_SPEED_SUPER_PLUS:
+		case USB_SPEED_SUPER_PLUS_BY2:
 			if (DWC3_IP_IS(DWC3))
 				reg |= DWC3_DCFG_SUPERSPEED;
 			else
@@ -3028,15 +3029,22 @@ static void dwc3_gadget_set_speed(struct usb_gadget *g,
 	spin_unlock_irqrestore(&dwc->lock, flags);
 }
 
-static void dwc3_gadget_set_ssp_rate(struct usb_gadget *g,
-				     enum usb_ssp_rate rate)
+static void dwc3_gadget_set_ssp_gen(struct usb_gadget *g,
+				    enum usb_ssp_gen gen)
 {
 	struct dwc3		*dwc = gadget_to_dwc(g);
 	unsigned long		flags;
 
 	spin_lock_irqsave(&dwc->lock, flags);
-	dwc->gadget_max_speed = USB_SPEED_SUPER_PLUS;
-	dwc->gadget_ssp_rate = rate;
+	switch (gen) {
+	case USB_SSP_GEN_2x2:
+		dwc->gadget_max_speed = USB_SPEED_SUPER_PLUS_BY2;
+		break;
+	default:
+		dwc->gadget_max_speed = USB_SPEED_SUPER_PLUS;
+		break;
+	}
+	dwc->gadget_ssp_gen = gen;
 	spin_unlock_irqrestore(&dwc->lock, flags);
 }
 
@@ -3123,7 +3131,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
 	.udc_start		= dwc3_gadget_start,
 	.udc_stop		= dwc3_gadget_stop,
 	.udc_set_speed		= dwc3_gadget_set_speed,
-	.udc_set_ssp_rate	= dwc3_gadget_set_ssp_rate,
+	.udc_set_ssp_gen	= dwc3_gadget_set_ssp_gen,
 	.get_config_params	= dwc3_gadget_config_params,
 	.vbus_draw		= dwc3_gadget_vbus_draw,
 	.check_config		= dwc3_gadget_check_config,
@@ -4071,7 +4079,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
 	if (DWC3_IP_IS(DWC32))
 		lanes = DWC3_DSTS_CONNLANES(reg) + 1;
 
-	dwc->gadget->ssp_rate = USB_SSP_GEN_UNKNOWN;
+	dwc->gadget->ssp_gen = USB_SSP_GEN_UNKNOWN;
 
 	/*
 	 * RAMClkSel is reset to 0 after USB reset, so it must be reprogrammed
@@ -4086,12 +4094,14 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
 	case DWC3_DSTS_SUPERSPEED_PLUS:
 		dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
 		dwc->gadget->ep0->maxpacket = 512;
-		dwc->gadget->speed = USB_SPEED_SUPER_PLUS;
 
-		if (lanes > 1)
-			dwc->gadget->ssp_rate = USB_SSP_GEN_2x2;
-		else
-			dwc->gadget->ssp_rate = USB_SSP_GEN_2x1;
+		if (lanes > 1) {
+			dwc->gadget->ssp_gen = USB_SSP_GEN_2x2;
+			dwc->gadget->speed = USB_SPEED_SUPER_PLUS_BY2;
+		} else {
+			dwc->gadget->ssp_gen = USB_SSP_GEN_2x1;
+			dwc->gadget->speed = USB_SPEED_SUPER_PLUS;
+		}
 		break;
 	case DWC3_DSTS_SUPERSPEED:
 		/*
@@ -4116,7 +4126,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
 
 		if (lanes > 1) {
 			dwc->gadget->speed = USB_SPEED_SUPER_PLUS;
-			dwc->gadget->ssp_rate = USB_SSP_GEN_1x2;
+			dwc->gadget->ssp_gen = USB_SSP_GEN_1x2;
 		}
 		break;
 	case DWC3_DSTS_HIGHSPEED:
@@ -4592,7 +4602,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 	dev->platform_data		= dwc;
 	dwc->gadget->ops		= &dwc3_gadget_ops;
 	dwc->gadget->speed		= USB_SPEED_UNKNOWN;
-	dwc->gadget->ssp_rate		= USB_SSP_GEN_UNKNOWN;
+	dwc->gadget->ssp_gen		= USB_SSP_GEN_UNKNOWN;
 	dwc->gadget->sg_supported	= true;
 	dwc->gadget->name		= "dwc3-gadget";
 	dwc->gadget->lpm_capable	= !dwc->usb2_gadget_lpm_disable;
@@ -4620,7 +4630,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 				dwc->revision);
 
 	dwc->gadget->max_speed		= dwc->maximum_speed;
-	dwc->gadget->max_ssp_rate	= dwc->max_ssp_rate;
+	dwc->gadget->max_ssp_gen	= dwc->max_ssp_gen;
 
 	/*
 	 * REVISIT: Here we should clear all pending IRQs to be
@@ -4637,8 +4647,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 		goto err5;
 	}
 
-	if (DWC3_IP_IS(DWC32) && dwc->maximum_speed == USB_SPEED_SUPER_PLUS)
-		dwc3_gadget_set_ssp_rate(dwc->gadget, dwc->max_ssp_rate);
+	if (DWC3_IP_IS(DWC32) && dwc->maximum_speed >= USB_SPEED_SUPER_PLUS)
+		dwc3_gadget_set_ssp_gen(dwc->gadget, dwc->max_ssp_gen);
 	else
 		dwc3_gadget_set_speed(dwc->gadget, dwc->maximum_speed);
 
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 0ace45b66a31..17f3b5e968a7 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -71,6 +71,7 @@ function_descriptors(struct usb_function *f,
 	 */
 
 	switch (speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
 	case USB_SPEED_SUPER_PLUS:
 		descriptors = f->ssp_descriptors;
 		if (descriptors)
@@ -169,6 +170,7 @@ int config_ep_by_speed_and_alt(struct usb_gadget *g,
 
 	/* select desired speed */
 	switch (g->speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
 	case USB_SPEED_SUPER_PLUS:
 		if (f->ssp_descriptors) {
 			speed_desc = f->ssp_descriptors;
@@ -650,6 +652,7 @@ static int config_desc(struct usb_composite_dev *cdev, unsigned w_value)
 check_config:
 		/* ignore configs that won't work at this speed */
 		switch (speed) {
+		case USB_SPEED_SUPER_PLUS_BY2:
 		case USB_SPEED_SUPER_PLUS:
 			if (!c->superspeed_plus)
 				continue;
@@ -688,8 +691,9 @@ static int count_configs(struct usb_composite_dev *cdev, unsigned type)
 			hs = 1;
 		if (gadget->speed == USB_SPEED_SUPER)
 			ss = 1;
-		if (gadget->speed == USB_SPEED_SUPER_PLUS)
+		if (gadget->speed >= USB_SPEED_SUPER_PLUS)
 			ssp = 1;
+
 		if (type == USB_DT_DEVICE_QUALIFIER)
 			hs = !hs;
 	}
@@ -803,7 +807,7 @@ static int bos_desc(struct usb_composite_dev *cdev)
 		u8 ssic;
 		int i;
 
-		if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x2)
+		if (cdev->gadget->max_ssp_gen == USB_SSP_GEN_2x2)
 			ssac = 3;
 
 		/*
@@ -850,8 +854,8 @@ static int bos_desc(struct usb_composite_dev *cdev)
 
 			ssid = i >> 1;
 
-			if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x1 ||
-			    cdev->gadget->max_ssp_rate == USB_SSP_GEN_UNKNOWN)
+			if (cdev->gadget->max_ssp_gen == USB_SSP_GEN_2x1 ||
+			    cdev->gadget->max_ssp_gen == USB_SSP_GEN_UNKNOWN)
 				mantissa = 10;
 			else
 				mantissa = 5 << ssid;
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 4c639e9ddedc..e85853bdacf7 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -327,18 +327,18 @@ static ssize_t gadget_dev_desc_max_speed_store(struct config_item *item,
 	if (gi->composite.gadget_driver.udc_name)
 		goto err;
 
-	if (strncmp(page, "super-speed-plus", 16) == 0)
-		gi->composite.max_speed = USB_SPEED_SUPER_PLUS;
-	else if (strncmp(page, "super-speed", 11) == 0)
-		gi->composite.max_speed = USB_SPEED_SUPER;
-	else if (strncmp(page, "high-speed", 10) == 0)
-		gi->composite.max_speed = USB_SPEED_HIGH;
-	else if (strncmp(page, "full-speed", 10) == 0)
-		gi->composite.max_speed = USB_SPEED_FULL;
-	else if (strncmp(page, "low-speed", 9) == 0)
-		gi->composite.max_speed = USB_SPEED_LOW;
-	else
+	gi->composite.max_speed = usb_speed_from_name(page);
+	switch (gi->composite.max_speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
+	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER:
+	case USB_SPEED_HIGH:
+	case USB_SPEED_FULL:
+	case USB_SPEED_LOW:
+		break;
+	default:
 		goto err;
+	}
 
 	gi->composite.gadget_driver.max_speed = gi->composite.max_speed;
 
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index f41a385a5c42..56e7b924f3c9 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1321,6 +1321,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
 		switch (epfile->ffs->gadget->speed) {
 		case USB_SPEED_SUPER:
 		case USB_SPEED_SUPER_PLUS:
+		case USB_SPEED_SUPER_PLUS_BY2:
 			desc_idx = 2;
 			break;
 		case USB_SPEED_HIGH:
diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c
index 2edbd9b510d6..e9bc2b9a1542 100644
--- a/drivers/usb/gadget/function/f_sourcesink.c
+++ b/drivers/usb/gadget/function/f_sourcesink.c
@@ -582,6 +582,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
 
 	if (is_iso) {
 		switch (speed) {
+		case USB_SPEED_SUPER_PLUS_BY2:
 		case USB_SPEED_SUPER_PLUS:
 		case USB_SPEED_SUPER:
 			size = ss->isoc_maxpacket *
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
index 0219cd79493a..0937f55c9c88 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -124,16 +124,6 @@ static struct usb_string strings_fn[] = {
 	{ },
 };
 
-static const char *const speed_names[] = {
-	[USB_SPEED_UNKNOWN] = "UNKNOWN",
-	[USB_SPEED_LOW] = "LS",
-	[USB_SPEED_FULL] = "FS",
-	[USB_SPEED_HIGH] = "HS",
-	[USB_SPEED_WIRELESS] = "W",
-	[USB_SPEED_SUPER] = "SS",
-	[USB_SPEED_SUPER_PLUS] = "SS+",
-};
-
 static struct usb_gadget_strings str_fn = {
 	.language = 0x0409,	/* en-us */
 	.strings = strings_fn,
@@ -763,11 +753,11 @@ static int set_ep_max_packet_size_bint(struct device *dev, const struct f_uac2_o
 	if (max_size_bw <= max_size_ep)
 		dev_dbg(dev,
 			"%s %s: Would use wMaxPacketSize %d and bInterval %d\n",
-			speed_names[speed], dir, max_size_bw, bint);
+			usb_speed_string(speed), dir, max_size_bw, bint);
 	else {
 		dev_warn(dev,
 			"%s %s: Req. wMaxPacketSize %d at bInterval %d > max ISOC %d, may drop data!\n",
-			speed_names[speed], dir, max_size_bw, bint, max_size_ep);
+			usb_speed_string(speed), dir, max_size_bw, bint, max_size_ep);
 		max_size_bw = max_size_ep;
 	}
 
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 7166d1117742..93773f60939b 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -1266,8 +1266,8 @@ static inline void usb_gadget_udc_set_speed(struct usb_udc *udc,
 	else
 		s = min(speed, gadget->max_speed);
 
-	if (s == USB_SPEED_SUPER_PLUS && gadget->ops->udc_set_ssp_rate)
-		gadget->ops->udc_set_ssp_rate(gadget, gadget->max_ssp_rate);
+	if (s >= USB_SPEED_SUPER_PLUS && gadget->ops->udc_set_ssp_gen)
+		gadget->ops->udc_set_ssp_gen(gadget, gadget->max_ssp_gen);
 	else if (gadget->ops->udc_set_speed)
 		gadget->ops->udc_set_speed(gadget, s);
 }
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 8714ab5bf04d..e26384b24aa6 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1087,25 +1087,31 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
 	/* 3) Only the control endpoint is valid - one endpoint context */
 	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route);
 	switch (udev->speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
 	case USB_SPEED_SUPER_PLUS:
-		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SSP);
+		slot_ctx->dev_info |= (xhci->hci_version < 0x120) ?
+					cpu_to_le32(SLOT_SPEED_SSP) : 0;
 		max_packets = MAX_PACKET(512);
 		break;
 	case USB_SPEED_SUPER:
-		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS);
+		slot_ctx->dev_info |= (xhci->hci_version < 0x120) ?
+					cpu_to_le32(SLOT_SPEED_SS) : 0;
 		max_packets = MAX_PACKET(512);
 		break;
 	case USB_SPEED_HIGH:
-		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_HS);
+		slot_ctx->dev_info |= (xhci->hci_version < 0x120) ?
+					cpu_to_le32(SLOT_SPEED_HS) : 0;
 		max_packets = MAX_PACKET(64);
 		break;
 	/* USB core guesses at a 64-byte max packet first for FS devices */
 	case USB_SPEED_FULL:
-		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_FS);
+		slot_ctx->dev_info |= (xhci->hci_version < 0x120) ?
+					cpu_to_le32(SLOT_SPEED_FS) : 0;
 		max_packets = MAX_PACKET(64);
 		break;
 	case USB_SPEED_LOW:
-		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_LS);
+		slot_ctx->dev_info |= (xhci->hci_version < 0x120) ?
+					cpu_to_le32(SLOT_SPEED_LS) : 0;
 		max_packets = MAX_PACKET(8);
 		break;
 	default:
@@ -1276,6 +1282,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
 		}
 		fallthrough;	/* SS and HS isoc/int have same decoding */
 
+	case USB_SPEED_SUPER_PLUS_BY2:
 	case USB_SPEED_SUPER_PLUS:
 	case USB_SPEED_SUPER:
 		if (usb_endpoint_xfer_int(&ep->desc) ||
diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 579899eb24c1..97318537612a 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -89,6 +89,7 @@ static u32 get_bw_boundary(enum usb_device_speed speed)
 	u32 boundary;
 
 	switch (speed) {
+	case USB_SPEED_SUPER_PLUS_BY2:
 	case USB_SPEED_SUPER_PLUS:
 		boundary = SSP_BW_BOUNDARY;
 		break;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index e1b1b64a0723..5483920a6ce9 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -2192,6 +2192,7 @@ static unsigned int xhci_get_block_size(struct usb_device *udev)
 		return HS_BLOCK;
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		return SS_BLOCK;
 	case USB_SPEED_UNKNOWN:
 	default:
@@ -5102,15 +5103,15 @@ static void xhci_hcd_init_usb3_data(struct xhci_hcd *xhci, struct usb_hcd *hcd)
 	switch (minor_rev) {
 	case 2:
 		hcd->speed = HCD_USB32;
-		hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
+		hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS_BY2;
 		hcd->self.root_hub->rx_lanes = 2;
 		hcd->self.root_hub->tx_lanes = 2;
-		hcd->self.root_hub->ssp_rate = USB_SSP_GEN_2x2;
+		hcd->self.root_hub->ssp_gen = USB_SSP_GEN_2x2;
 		break;
 	case 1:
 		hcd->speed = HCD_USB31;
 		hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
-		hcd->self.root_hub->ssp_rate = USB_SSP_GEN_2x1;
+		hcd->self.root_hub->ssp_gen = USB_SSP_GEN_2x1;
 		break;
 	}
 	xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n",
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 7e282b4522c0..ec507770a559 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -345,7 +345,10 @@ struct xhci_op_regs {
 #define DEV_SUPERSPEED_ANY(p)	(((p) & DEV_SPEED_MASK) >= XDEV_SS)
 #define DEV_PORT_SPEED(p)	(((p) >> 10) & 0x0f)
 
-/* Bits 20:23 in the Slot Context are the speed for the device */
+/* Bits 20:23 in the Slot Context are the speed for the device.
+ * This field has been deprecated since xHCI spec revision 1.2
+ * and shall be reserved.
+ */
 #define	SLOT_SPEED_FS		(XDEV_FS << 10)
 #define	SLOT_SPEED_LS		(XDEV_LS << 10)
 #define	SLOT_SPEED_HS		(XDEV_HS << 10)
diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index a3a6282893d0..346df653a1e4 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -254,6 +254,7 @@ static void mtu3_set_speed(struct mtu3 *mtu, enum usb_device_speed speed)
 			     SSUSB_U3_PORT_SSP_SPEED);
 		break;
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
 		mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
 			     SSUSB_U3_PORT_SSP_SPEED);
@@ -831,6 +832,7 @@ static void mtu3_check_params(struct mtu3 *mtu)
 	case USB_SPEED_HIGH:
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		break;
 	default:
 		dev_err(mtu->dev, "invalid max_speed: %s\n",
diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index ad0eeac4332d..1545d139907c 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -74,6 +74,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 	switch (mtu->g.speed) {
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		if (usb_endpoint_xfer_int(desc) ||
 				usb_endpoint_xfer_isoc(desc)) {
 			interval = desc->bInterval;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index a21074861f91..af8674d95820 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -657,7 +657,7 @@ struct usb_device {
 	enum usb_device_speed	speed;
 	unsigned int		rx_lanes;
 	unsigned int		tx_lanes;
-	enum usb_ssp_rate	ssp_rate;
+	enum usb_ssp_gen	ssp_gen;
 
 	struct usb_tt	*tt;
 	int		ttport;
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index c93b410b314a..bf9d66399d46 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -32,21 +32,15 @@
 
 #include <uapi/linux/usb/ch9.h>
 
-/* USB 3.2 SuperSpeed Plus phy signaling rate generation and lane count */
-
-enum usb_ssp_rate {
-	USB_SSP_GEN_UNKNOWN = 0,
-	USB_SSP_GEN_2x1,
-	USB_SSP_GEN_1x2,
-	USB_SSP_GEN_2x2,
-};
-
 struct device;
 
 extern const char *usb_ep_type_string(int ep_type);
 extern const char *usb_speed_string(enum usb_device_speed speed);
+extern const char *usb_speed_value(enum usb_device_speed speed);
+extern const char *usb_ssp_gen_name(enum usb_ssp_gen gen);
+extern enum usb_device_speed usb_speed_from_name(const char *speed_name);
 extern enum usb_device_speed usb_get_maximum_speed(struct device *dev);
-extern enum usb_ssp_rate usb_get_maximum_ssp_rate(struct device *dev);
+extern enum usb_ssp_gen usb_get_maximum_ssp_gen(struct device *dev);
 extern const char *usb_state_string(enum usb_device_state state);
 unsigned int usb_decode_interval(const struct usb_endpoint_descriptor *epd,
 				 enum usb_device_speed speed);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 75bda0783395..6f8040e3e29b 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -324,8 +324,8 @@ struct usb_gadget_ops {
 			struct usb_gadget_driver *);
 	int	(*udc_stop)(struct usb_gadget *);
 	void	(*udc_set_speed)(struct usb_gadget *, enum usb_device_speed);
-	void	(*udc_set_ssp_rate)(struct usb_gadget *gadget,
-			enum usb_ssp_rate rate);
+	void	(*udc_set_ssp_gen)(struct usb_gadget *gadget,
+			enum usb_ssp_gen gen);
 	void	(*udc_async_callbacks)(struct usb_gadget *gadget, bool enable);
 	struct usb_ep *(*match_ep)(struct usb_gadget *,
 			struct usb_endpoint_descriptor *,
@@ -420,8 +420,8 @@ struct usb_gadget {
 	enum usb_device_speed		max_speed;
 
 	/* USB SuperSpeed Plus only */
-	enum usb_ssp_rate		ssp_rate;
-	enum usb_ssp_rate		max_ssp_rate;
+	enum usb_ssp_gen		ssp_gen;
+	enum usb_ssp_gen		max_ssp_gen;
 
 	enum usb_device_state		state;
 	const char			*name;
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
index 8a147abfc680..3522e2c20599 100644
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -1181,10 +1181,19 @@ enum usb_device_speed {
 	USB_SPEED_LOW, USB_SPEED_FULL,		/* usb 1.1 */
 	USB_SPEED_HIGH,				/* usb 2.0 */
 	USB_SPEED_WIRELESS,			/* wireless (usb 2.5) */
-	USB_SPEED_SUPER,			/* usb 3.0 */
-	USB_SPEED_SUPER_PLUS,			/* usb 3.1 */
+	USB_SPEED_SUPER,			/* usb 3.0 5Gbps */
+	USB_SPEED_SUPER_PLUS,			/* usb 3.1 10Gbps */
+	USB_SPEED_SUPER_PLUS_BY2,		/* usb 3.2 20Gbps */
 };
 
+/* USB 3.2 SuperSpeed Plus phy signaling generation and lane count */
+
+enum usb_ssp_gen {
+	USB_SSP_GEN_UNKNOWN = 0,
+	USB_SSP_GEN_2x1,
+	USB_SSP_GEN_1x2,
+	USB_SSP_GEN_2x2,
+};
 
 enum usb_device_state {
 	/* NOTATTACHED isn't in the USB spec, and this state acts
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 1b2edc0fd2e9..13c7da24571b 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -571,19 +571,15 @@ static void usb_audio_make_longname(struct usb_device *dev,
 
 	switch (snd_usb_get_speed(dev)) {
 	case USB_SPEED_LOW:
-		strlcat(card->longname, ", low speed", sizeof(card->longname));
-		break;
 	case USB_SPEED_FULL:
-		strlcat(card->longname, ", full speed", sizeof(card->longname));
-		break;
 	case USB_SPEED_HIGH:
-		strlcat(card->longname, ", high speed", sizeof(card->longname));
-		break;
 	case USB_SPEED_SUPER:
-		strlcat(card->longname, ", super speed", sizeof(card->longname));
-		break;
 	case USB_SPEED_SUPER_PLUS:
-		strlcat(card->longname, ", super speed plus", sizeof(card->longname));
+	case USB_SPEED_SUPER_PLUS_BY2:
+		strlcat(card->longname, ", ", sizeof(card->longname));
+		strlcat(card->longname,
+			usb_speed_string(snd_usb_get_speed(dev)),
+			sizeof(card->longname));
 		break;
 	default:
 		break;
@@ -612,6 +608,7 @@ static int snd_usb_audio_create(struct usb_interface *intf,
 	case USB_SPEED_HIGH:
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		break;
 	default:
 		dev_err(&dev->dev, "unknown device speed %d\n", snd_usb_get_speed(dev));
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
index bf80e55d013a..0cac8e0177e4 100644
--- a/sound/usb/helper.c
+++ b/sound/usb/helper.c
@@ -110,6 +110,7 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
 	case USB_SPEED_HIGH:
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		if (get_endpoint(alts, 0)->bInterval >= 1 &&
 		    get_endpoint(alts, 0)->bInterval <= 4)
 			return get_endpoint(alts, 0)->bInterval - 1;
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 6b0993258e03..47159aaba8d5 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -897,6 +897,7 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
 	case USB_SPEED_HIGH:
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
+	case USB_SPEED_SUPER_PLUS_BY2:
 		count = 1;
 		break;
 	default:
diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c
index cbaa1b9fdeac..6f6675c92e0c 100644
--- a/tools/usb/testusb.c
+++ b/tools/usb/testusb.c
@@ -98,8 +98,9 @@ enum usb_device_speed {
 	USB_SPEED_LOW, USB_SPEED_FULL,		/* usb 1.1 */
 	USB_SPEED_HIGH,				/* usb 2.0 */
 	USB_SPEED_WIRELESS,			/* wireless (usb 2.5) */
-	USB_SPEED_SUPER,			/* usb 3.0 */
-	USB_SPEED_SUPER_PLUS,			/* usb 3.1 */
+	USB_SPEED_SUPER,			/* usb 3.0 5Gbps */
+	USB_SPEED_SUPER_PLUS,			/* usb 3.1 10Gbps */
+	USB_SPEED_SUPER_PLUS_BY2,		/* usb 3.2 20Gbps */
 };
 
 /*-------------------------------------------------------------------------*/
@@ -114,6 +115,7 @@ static char *speed (enum usb_device_speed s)
 	case USB_SPEED_WIRELESS:	return "wireless";
 	case USB_SPEED_SUPER:		return "super";
 	case USB_SPEED_SUPER_PLUS:	return "super-plus";
+	case USB_SPEED_SUPER_PLUS_BY2:	return "super-plus-by2";
 	default:			return "??";
 	}
 }
