usb: common: Parse for USB SSP genXxY
authorThinh Nguyen <Thinh.Nguyen@synopsys.com>
Wed, 20 Jan 2021 01:36:14 +0000 (17:36 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 6 Feb 2021 13:21:21 +0000 (14:21 +0100)
The USB "maximum-speed" property can now take the SSP signaling rate
generation and lane count with these new strings:

"super-speed-plus-gen2x2"
"super-speed-plus-gen2x1"
"super-speed-plus-gen1x2"

Introduce usb_get_maximum_ssp_rate() to parse for the corresponding
usb_ssp_rate enum. The original usb_get_maximum_speed() will return
USB_SPEED_SUPER_PLUS if it matches one of these new strings.

Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/f8ed896313d8cd8e2d2b540fc82db92b3ddf8a47.1611106162.git.Thinh.Nguyen@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/common/common.c
include/linux/usb/ch9.h

index 1433260..fc21cf2 100644 (file)
@@ -69,6 +69,13 @@ static const char *const speed_names[] = {
        [USB_SPEED_SUPER_PLUS] = "super-speed-plus",
 };
 
+static const char *const ssp_rate[] = {
+       [USB_SSP_GEN_UNKNOWN] = "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",
+};
+
 const char *usb_speed_string(enum usb_device_speed speed)
 {
        if (speed < 0 || speed >= ARRAY_SIZE(speed_names))
@@ -86,12 +93,29 @@ enum usb_device_speed usb_get_maximum_speed(struct device *dev)
        if (ret < 0)
                return USB_SPEED_UNKNOWN;
 
-       ret = match_string(speed_names, ARRAY_SIZE(speed_names), maximum_speed);
+       ret = match_string(ssp_rate, ARRAY_SIZE(ssp_rate), maximum_speed);
+       if (ret > 0)
+               return USB_SPEED_SUPER_PLUS;
 
+       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);
 
+enum usb_ssp_rate usb_get_maximum_ssp_rate(struct device *dev)
+{
+       const char *maximum_speed;
+       int ret;
+
+       ret = device_property_read_string(dev, "maximum-speed", &maximum_speed);
+       if (ret < 0)
+               return USB_SSP_GEN_UNKNOWN;
+
+       ret = match_string(ssp_rate, ARRAY_SIZE(ssp_rate), maximum_speed);
+       return (ret < 0) ? USB_SSP_GEN_UNKNOWN : ret;
+}
+EXPORT_SYMBOL_GPL(usb_get_maximum_ssp_rate);
+
 const char *usb_state_string(enum usb_device_state state)
 {
        static const char *const names[] = {
index 86c5090..abdd310 100644 (file)
@@ -72,6 +72,17 @@ extern const char *usb_speed_string(enum usb_device_speed speed);
 extern enum usb_device_speed usb_get_maximum_speed(struct device *dev);
 
 /**
+ * usb_get_maximum_ssp_rate - Get the signaling rate 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.
+ */
+extern enum usb_ssp_rate usb_get_maximum_ssp_rate(struct device *dev);
+
+/**
  * usb_state_string - Returns human readable name for the state.
  * @state: The state to return a human-readable name for. If it's not
  *     any of the states devices in usb_device_state_string enum,