* [PATCH v5 1/4] usb: typec: Add mode_control field to port property
2025-11-24 12:46 [PATCH v5 0/4] USB Type-C alternate mode priorities Andrei Kuchynski
@ 2025-11-24 12:46 ` Andrei Kuchynski
2025-11-25 0:13 ` Benson Leung
2025-11-24 12:46 ` [PATCH v5 2/4] platform/chrome: cros_ec_typec: Set no_mode_control flag Andrei Kuchynski
` (3 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Andrei Kuchynski @ 2025-11-24 12:46 UTC (permalink / raw)
To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
Christian A. Ehrhardt, Abel Vesa, Pooja Katiyar, Venkat Jayaraman,
linux-kernel, Andrei Kuchynski
This new field in the port properties dictates whether the Platform Policy
Manager (PPM) allows the OS Policy Manager (OPM) to change the currently
active, negotiated alternate mode.
Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
drivers/usb/typec/class.c | 9 ++++++---
drivers/usb/typec/class.h | 1 +
include/linux/usb/typec.h | 2 ++
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9b2647cb199b..a5327e444265 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -457,11 +457,13 @@ static umode_t typec_altmode_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj));
+ struct typec_port *port = typec_altmode2port(adev);
if (attr == &dev_attr_active.attr)
- if (!is_typec_port(adev->dev.parent) &&
- (!adev->ops || !adev->ops->activate))
- return 0444;
+ if (!is_typec_port(adev->dev.parent)) {
+ if (!port->mode_control || !adev->ops || !adev->ops->activate)
+ return 0444;
+ }
return attr->mode;
}
@@ -2694,6 +2696,7 @@ struct typec_port *typec_register_port(struct device *parent,
}
port->pd = cap->pd;
+ port->mode_control = !cap->no_mode_control;
ret = device_add(&port->dev);
if (ret) {
diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h
index db2fe96c48ff..2e89a83c2eb7 100644
--- a/drivers/usb/typec/class.h
+++ b/drivers/usb/typec/class.h
@@ -62,6 +62,7 @@ struct typec_port {
struct mutex partner_link_lock;
enum typec_orientation orientation;
+ bool mode_control;
struct typec_switch *sw;
struct typec_mux *mux;
struct typec_retimer *retimer;
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 309251572e2e..59d5fd7e4ff4 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -287,6 +287,7 @@ enum usb_pd_svdm_ver {
* @prefer_role: Initial role preference (DRP ports).
* @accessory: Supported Accessory Modes
* @usb_capability: Supported USB Modes
+ * @no_mode_control: Ability to manage Alternate Modes
* @fwnode: Optional fwnode of the port
* @driver_data: Private pointer for driver specific info
* @pd: Optional USB Power Delivery Support
@@ -304,6 +305,7 @@ struct typec_capability {
enum typec_accessory accessory[TYPEC_MAX_ACCESSORY];
unsigned int orientation_aware:1;
u8 usb_capability;
+ bool no_mode_control;
struct fwnode_handle *fwnode;
void *driver_data;
--
2.52.0.rc2.455.g230fcf2819-goog
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v5 1/4] usb: typec: Add mode_control field to port property
2025-11-24 12:46 ` [PATCH v5 1/4] usb: typec: Add mode_control field to port property Andrei Kuchynski
@ 2025-11-25 0:13 ` Benson Leung
0 siblings, 0 replies; 12+ messages in thread
From: Benson Leung @ 2025-11-25 0:13 UTC (permalink / raw)
To: Andrei Kuchynski
Cc: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform,
Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
Christian A. Ehrhardt, Abel Vesa, Pooja Katiyar, Venkat Jayaraman,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2997 bytes --]
Hi Andrei,
On Mon, Nov 24, 2025 at 12:46:36PM +0000, Andrei Kuchynski wrote:
> This new field in the port properties dictates whether the Platform Policy
> Manager (PPM) allows the OS Policy Manager (OPM) to change the currently
> active, negotiated alternate mode.
>
> Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Benson Leung <bleung@chromium.org>
> ---
> drivers/usb/typec/class.c | 9 ++++++---
> drivers/usb/typec/class.h | 1 +
> include/linux/usb/typec.h | 2 ++
> 3 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
> index 9b2647cb199b..a5327e444265 100644
> --- a/drivers/usb/typec/class.c
> +++ b/drivers/usb/typec/class.c
> @@ -457,11 +457,13 @@ static umode_t typec_altmode_attr_is_visible(struct kobject *kobj,
> struct attribute *attr, int n)
> {
> struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj));
> + struct typec_port *port = typec_altmode2port(adev);
>
> if (attr == &dev_attr_active.attr)
> - if (!is_typec_port(adev->dev.parent) &&
> - (!adev->ops || !adev->ops->activate))
> - return 0444;
> + if (!is_typec_port(adev->dev.parent)) {
> + if (!port->mode_control || !adev->ops || !adev->ops->activate)
> + return 0444;
> + }
>
> return attr->mode;
> }
> @@ -2694,6 +2696,7 @@ struct typec_port *typec_register_port(struct device *parent,
> }
>
> port->pd = cap->pd;
> + port->mode_control = !cap->no_mode_control;
>
> ret = device_add(&port->dev);
> if (ret) {
> diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h
> index db2fe96c48ff..2e89a83c2eb7 100644
> --- a/drivers/usb/typec/class.h
> +++ b/drivers/usb/typec/class.h
> @@ -62,6 +62,7 @@ struct typec_port {
> struct mutex partner_link_lock;
>
> enum typec_orientation orientation;
> + bool mode_control;
> struct typec_switch *sw;
> struct typec_mux *mux;
> struct typec_retimer *retimer;
> diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
> index 309251572e2e..59d5fd7e4ff4 100644
> --- a/include/linux/usb/typec.h
> +++ b/include/linux/usb/typec.h
> @@ -287,6 +287,7 @@ enum usb_pd_svdm_ver {
> * @prefer_role: Initial role preference (DRP ports).
> * @accessory: Supported Accessory Modes
> * @usb_capability: Supported USB Modes
> + * @no_mode_control: Ability to manage Alternate Modes
> * @fwnode: Optional fwnode of the port
> * @driver_data: Private pointer for driver specific info
> * @pd: Optional USB Power Delivery Support
> @@ -304,6 +305,7 @@ struct typec_capability {
> enum typec_accessory accessory[TYPEC_MAX_ACCESSORY];
> unsigned int orientation_aware:1;
> u8 usb_capability;
> + bool no_mode_control;
>
> struct fwnode_handle *fwnode;
> void *driver_data;
> --
> 2.52.0.rc2.455.g230fcf2819-goog
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v5 2/4] platform/chrome: cros_ec_typec: Set no_mode_control flag
2025-11-24 12:46 [PATCH v5 0/4] USB Type-C alternate mode priorities Andrei Kuchynski
2025-11-24 12:46 ` [PATCH v5 1/4] usb: typec: Add mode_control field to port property Andrei Kuchynski
@ 2025-11-24 12:46 ` Andrei Kuchynski
2025-11-25 0:15 ` Benson Leung
2025-11-24 12:46 ` [PATCH v5 3/4] usb: typec: ucsi: " Andrei Kuchynski
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Andrei Kuchynski @ 2025-11-24 12:46 UTC (permalink / raw)
To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
Christian A. Ehrhardt, Abel Vesa, Pooja Katiyar, Venkat Jayaraman,
linux-kernel, Andrei Kuchynski
This flag specifies that the Embedded Controller (EC) must receive explicit
approval from the Application Processor (AP) before initiating Type-C
alternate modes or USB4 mode.
Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: Tzung-Bi Shih <tzungbi@kernel.org>
---
drivers/platform/chrome/cros_ec_typec.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index b712bcff6fb2..c0806c562bb9 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -491,6 +491,7 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
cap->driver_data = cros_port;
cap->ops = &cros_typec_usb_mode_ops;
+ cap->no_mode_control = !typec->ap_driven_altmode;
cros_port->port = typec_register_port(dev, cap);
if (IS_ERR(cros_port->port)) {
--
2.52.0.rc2.455.g230fcf2819-goog
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v5 2/4] platform/chrome: cros_ec_typec: Set no_mode_control flag
2025-11-24 12:46 ` [PATCH v5 2/4] platform/chrome: cros_ec_typec: Set no_mode_control flag Andrei Kuchynski
@ 2025-11-25 0:15 ` Benson Leung
0 siblings, 0 replies; 12+ messages in thread
From: Benson Leung @ 2025-11-25 0:15 UTC (permalink / raw)
To: Andrei Kuchynski
Cc: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform,
Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
Christian A. Ehrhardt, Abel Vesa, Pooja Katiyar, Venkat Jayaraman,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1203 bytes --]
Hi Andrei,
On Mon, Nov 24, 2025 at 12:46:37PM +0000, Andrei Kuchynski wrote:
> This flag specifies that the Embedded Controller (EC) must receive explicit
> approval from the Application Processor (AP) before initiating Type-C
> alternate modes or USB4 mode.
>
> Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Acked-by: Tzung-Bi Shih <tzungbi@kernel.org>
Reviewed-by: Benson Leung <bleung@chromium.org>
> ---
> drivers/platform/chrome/cros_ec_typec.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
> index b712bcff6fb2..c0806c562bb9 100644
> --- a/drivers/platform/chrome/cros_ec_typec.c
> +++ b/drivers/platform/chrome/cros_ec_typec.c
> @@ -491,6 +491,7 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
>
> cap->driver_data = cros_port;
> cap->ops = &cros_typec_usb_mode_ops;
> + cap->no_mode_control = !typec->ap_driven_altmode;
>
> cros_port->port = typec_register_port(dev, cap);
> if (IS_ERR(cros_port->port)) {
> --
> 2.52.0.rc2.455.g230fcf2819-goog
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v5 3/4] usb: typec: ucsi: Set no_mode_control flag
2025-11-24 12:46 [PATCH v5 0/4] USB Type-C alternate mode priorities Andrei Kuchynski
2025-11-24 12:46 ` [PATCH v5 1/4] usb: typec: Add mode_control field to port property Andrei Kuchynski
2025-11-24 12:46 ` [PATCH v5 2/4] platform/chrome: cros_ec_typec: Set no_mode_control flag Andrei Kuchynski
@ 2025-11-24 12:46 ` Andrei Kuchynski
2025-11-25 0:16 ` Benson Leung
2025-11-24 12:46 ` [PATCH v5 4/4] usb: typec: Expose alternate mode priority via sysfs Andrei Kuchynski
2025-11-26 9:23 ` [PATCH v5 0/4] USB Type-C alternate mode priorities Heikki Krogerus
4 siblings, 1 reply; 12+ messages in thread
From: Andrei Kuchynski @ 2025-11-24 12:46 UTC (permalink / raw)
To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
Christian A. Ehrhardt, Abel Vesa, Pooja Katiyar, Venkat Jayaraman,
linux-kernel, Andrei Kuchynski
This flag indicates that the PPM allows the OPM to change the currently
negotiated alternate mode using the SET_NEW_CAM command.
Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
---
drivers/usb/typec/ucsi/ucsi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 9b3df776137a..82c3efd72639 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1700,6 +1700,7 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
cap->driver_data = con;
cap->ops = &ucsi_ops;
+ cap->no_mode_control = !(con->ucsi->cap.features & UCSI_CAP_ALT_MODE_OVERRIDE);
if (ucsi->version >= UCSI_VERSION_2_0)
con->typec_cap.orientation_aware = true;
--
2.52.0.rc2.455.g230fcf2819-goog
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v5 3/4] usb: typec: ucsi: Set no_mode_control flag
2025-11-24 12:46 ` [PATCH v5 3/4] usb: typec: ucsi: " Andrei Kuchynski
@ 2025-11-25 0:16 ` Benson Leung
0 siblings, 0 replies; 12+ messages in thread
From: Benson Leung @ 2025-11-25 0:16 UTC (permalink / raw)
To: Andrei Kuchynski
Cc: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform,
Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
Christian A. Ehrhardt, Abel Vesa, Pooja Katiyar, Venkat Jayaraman,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 995 bytes --]
On Mon, Nov 24, 2025 at 12:46:38PM +0000, Andrei Kuchynski wrote:
> This flag indicates that the PPM allows the OPM to change the currently
> negotiated alternate mode using the SET_NEW_CAM command.
>
> Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
Reviewed-by: Benson Leung <bleung@chromium.org>
> ---
> drivers/usb/typec/ucsi/ucsi.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> index 9b3df776137a..82c3efd72639 100644
> --- a/drivers/usb/typec/ucsi/ucsi.c
> +++ b/drivers/usb/typec/ucsi/ucsi.c
> @@ -1700,6 +1700,7 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
>
> cap->driver_data = con;
> cap->ops = &ucsi_ops;
> + cap->no_mode_control = !(con->ucsi->cap.features & UCSI_CAP_ALT_MODE_OVERRIDE);
>
> if (ucsi->version >= UCSI_VERSION_2_0)
> con->typec_cap.orientation_aware = true;
> --
> 2.52.0.rc2.455.g230fcf2819-goog
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v5 4/4] usb: typec: Expose alternate mode priority via sysfs
2025-11-24 12:46 [PATCH v5 0/4] USB Type-C alternate mode priorities Andrei Kuchynski
` (2 preceding siblings ...)
2025-11-24 12:46 ` [PATCH v5 3/4] usb: typec: ucsi: " Andrei Kuchynski
@ 2025-11-24 12:46 ` Andrei Kuchynski
2025-11-24 14:25 ` Abel Vesa
2025-11-25 0:20 ` Benson Leung
2025-11-26 9:23 ` [PATCH v5 0/4] USB Type-C alternate mode priorities Heikki Krogerus
4 siblings, 2 replies; 12+ messages in thread
From: Andrei Kuchynski @ 2025-11-24 12:46 UTC (permalink / raw)
To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
Christian A. Ehrhardt, Abel Vesa, Pooja Katiyar, Venkat Jayaraman,
linux-kernel, Andrei Kuchynski
This patch introduces a priority sysfs attribute to the USB Type-C
alternate mode port interface. This new attribute allows user-space to
configure the numeric priority of alternate modes managing their preferred
order of operation. If a new priority value conflicts with an existing
mode's priority, the priorities of the conflicting mode and all subsequent
modes are automatically incremented to ensure uniqueness.
Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
---
Documentation/ABI/testing/sysfs-class-typec | 11 +++
drivers/usb/typec/class.c | 90 ++++++++++++++++++++-
include/linux/usb/typec_altmode.h | 1 +
3 files changed, 101 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/ABI/testing/sysfs-class-typec
index 38e101c17a00..737b76828b50 100644
--- a/Documentation/ABI/testing/sysfs-class-typec
+++ b/Documentation/ABI/testing/sysfs-class-typec
@@ -162,6 +162,17 @@ Description: Lists the supported USB Modes. The default USB mode that is used
- usb3 (USB 3.2)
- usb4 (USB4)
+What: /sys/class/typec/<port>/<alt-mode>/priority
+Date: July 2025
+Contact: Andrei Kuchynski <akuchynski@chromium.org>
+Description:
+ Displays and allows setting the priority for a specific alternate mode.
+ The priority is an integer in the range 0-255. A lower numerical value
+ indicates a higher priority (0 is the highest).
+ If the new value is already in use by another mode, the priority of the
+ conflicting mode and any subsequent modes will be incremented until they
+ are all unique.
+
USB Type-C partner devices (eg. /sys/class/typec/port0-partner/)
What: /sys/class/typec/<port>-partner/accessory_mode
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index a5327e444265..049d1829be98 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -445,11 +445,88 @@ svid_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static DEVICE_ATTR_RO(svid);
+static int increment_duplicated_priority(struct device *dev, void *data)
+{
+ if (is_typec_altmode(dev)) {
+ struct typec_altmode **alt_target = (struct typec_altmode **)data;
+ struct typec_altmode *alt = to_typec_altmode(dev);
+
+ if (alt != *alt_target && alt->priority == (*alt_target)->priority) {
+ alt->priority++;
+ *alt_target = alt;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int find_duplicated_priority(struct device *dev, void *data)
+{
+ if (is_typec_altmode(dev)) {
+ struct typec_altmode **alt_target = (struct typec_altmode **)data;
+ struct typec_altmode *alt = to_typec_altmode(dev);
+
+ if (alt != *alt_target && alt->priority == (*alt_target)->priority)
+ return 1;
+ }
+ return 0;
+}
+
+static int typec_mode_set_priority(struct typec_altmode *alt, const u8 priority)
+{
+ struct typec_port *port = to_typec_port(alt->dev.parent);
+ const u8 old_priority = alt->priority;
+ int res = 1;
+
+ alt->priority = priority;
+ while (res) {
+ res = device_for_each_child(&port->dev, &alt, find_duplicated_priority);
+ if (res) {
+ alt->priority++;
+ if (alt->priority == 0) {
+ alt->priority = old_priority;
+ return -EOVERFLOW;
+ }
+ }
+ }
+
+ res = 1;
+ alt->priority = priority;
+ while (res)
+ res = device_for_each_child(&port->dev, &alt,
+ increment_duplicated_priority);
+
+ return 0;
+}
+
+static ssize_t priority_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 val;
+ int err = kstrtou8(buf, 10, &val);
+
+ if (!err)
+ err = typec_mode_set_priority(to_typec_altmode(dev), val);
+
+ if (!err)
+ return size;
+ return err;
+}
+
+static ssize_t priority_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "%u\n", to_typec_altmode(dev)->priority);
+}
+static DEVICE_ATTR_RW(priority);
+
static struct attribute *typec_altmode_attrs[] = {
&dev_attr_active.attr,
&dev_attr_mode.attr,
&dev_attr_svid.attr,
&dev_attr_vdo.attr,
+ &dev_attr_priority.attr,
NULL
};
@@ -459,11 +536,15 @@ static umode_t typec_altmode_attr_is_visible(struct kobject *kobj,
struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj));
struct typec_port *port = typec_altmode2port(adev);
- if (attr == &dev_attr_active.attr)
+ if (attr == &dev_attr_active.attr) {
if (!is_typec_port(adev->dev.parent)) {
if (!port->mode_control || !adev->ops || !adev->ops->activate)
return 0444;
}
+ } else if (attr == &dev_attr_priority.attr) {
+ if (!is_typec_port(adev->dev.parent) || !port->mode_control)
+ return 0;
+ }
return attr->mode;
}
@@ -2484,6 +2565,7 @@ typec_port_register_altmode(struct typec_port *port,
struct typec_altmode *adev;
struct typec_mux *mux;
struct typec_retimer *retimer;
+ int ret;
mux = typec_mux_get(&port->dev);
if (IS_ERR(mux))
@@ -2502,6 +2584,12 @@ typec_port_register_altmode(struct typec_port *port,
} else {
to_altmode(adev)->mux = mux;
to_altmode(adev)->retimer = retimer;
+
+ ret = typec_mode_set_priority(adev, 0);
+ if (ret) {
+ typec_unregister_altmode(adev);
+ return ERR_PTR(ret);
+ }
}
return adev;
diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
index f7db3bd4c90e..2c3b6bec2eca 100644
--- a/include/linux/usb/typec_altmode.h
+++ b/include/linux/usb/typec_altmode.h
@@ -28,6 +28,7 @@ struct typec_altmode {
int mode;
u32 vdo;
unsigned int active:1;
+ u8 priority;
char *desc;
const struct typec_altmode_ops *ops;
--
2.52.0.rc2.455.g230fcf2819-goog
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v5 4/4] usb: typec: Expose alternate mode priority via sysfs
2025-11-24 12:46 ` [PATCH v5 4/4] usb: typec: Expose alternate mode priority via sysfs Andrei Kuchynski
@ 2025-11-24 14:25 ` Abel Vesa
2025-11-25 0:20 ` Benson Leung
1 sibling, 0 replies; 12+ messages in thread
From: Abel Vesa @ 2025-11-24 14:25 UTC (permalink / raw)
To: Andrei Kuchynski
Cc: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform,
Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
Christian A. Ehrhardt, Pooja Katiyar, Venkat Jayaraman,
linux-kernel
On 25-11-24 12:46:39, Andrei Kuchynski wrote:
> This patch introduces a priority sysfs attribute to the USB Type-C
Please read submitting patches doc. No "This patch ..." stuff.
The rest of the patch looks OK.
> alternate mode port interface. This new attribute allows user-space to
> configure the numeric priority of alternate modes managing their preferred
> order of operation. If a new priority value conflicts with an existing
> mode's priority, the priorities of the conflicting mode and all subsequent
> modes are automatically incremented to ensure uniqueness.
>
> Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 4/4] usb: typec: Expose alternate mode priority via sysfs
2025-11-24 12:46 ` [PATCH v5 4/4] usb: typec: Expose alternate mode priority via sysfs Andrei Kuchynski
2025-11-24 14:25 ` Abel Vesa
@ 2025-11-25 0:20 ` Benson Leung
1 sibling, 0 replies; 12+ messages in thread
From: Benson Leung @ 2025-11-25 0:20 UTC (permalink / raw)
To: Andrei Kuchynski
Cc: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform,
Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
Christian A. Ehrhardt, Abel Vesa, Pooja Katiyar, Venkat Jayaraman,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 6268 bytes --]
On Mon, Nov 24, 2025 at 12:46:39PM +0000, Andrei Kuchynski wrote:
> This patch introduces a priority sysfs attribute to the USB Type-C
> alternate mode port interface. This new attribute allows user-space to
> configure the numeric priority of alternate modes managing their preferred
> order of operation. If a new priority value conflicts with an existing
> mode's priority, the priorities of the conflicting mode and all subsequent
> modes are automatically incremented to ensure uniqueness.
>
> Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
Reviewed-by: Benson Leung <bleung@chromium.org>
> ---
> Documentation/ABI/testing/sysfs-class-typec | 11 +++
> drivers/usb/typec/class.c | 90 ++++++++++++++++++++-
> include/linux/usb/typec_altmode.h | 1 +
> 3 files changed, 101 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/ABI/testing/sysfs-class-typec
> index 38e101c17a00..737b76828b50 100644
> --- a/Documentation/ABI/testing/sysfs-class-typec
> +++ b/Documentation/ABI/testing/sysfs-class-typec
> @@ -162,6 +162,17 @@ Description: Lists the supported USB Modes. The default USB mode that is used
> - usb3 (USB 3.2)
> - usb4 (USB4)
>
> +What: /sys/class/typec/<port>/<alt-mode>/priority
> +Date: July 2025
> +Contact: Andrei Kuchynski <akuchynski@chromium.org>
> +Description:
> + Displays and allows setting the priority for a specific alternate mode.
> + The priority is an integer in the range 0-255. A lower numerical value
> + indicates a higher priority (0 is the highest).
> + If the new value is already in use by another mode, the priority of the
> + conflicting mode and any subsequent modes will be incremented until they
> + are all unique.
> +
> USB Type-C partner devices (eg. /sys/class/typec/port0-partner/)
>
> What: /sys/class/typec/<port>-partner/accessory_mode
> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
> index a5327e444265..049d1829be98 100644
> --- a/drivers/usb/typec/class.c
> +++ b/drivers/usb/typec/class.c
> @@ -445,11 +445,88 @@ svid_show(struct device *dev, struct device_attribute *attr, char *buf)
> }
> static DEVICE_ATTR_RO(svid);
>
> +static int increment_duplicated_priority(struct device *dev, void *data)
> +{
> + if (is_typec_altmode(dev)) {
> + struct typec_altmode **alt_target = (struct typec_altmode **)data;
> + struct typec_altmode *alt = to_typec_altmode(dev);
> +
> + if (alt != *alt_target && alt->priority == (*alt_target)->priority) {
> + alt->priority++;
> + *alt_target = alt;
> + return 1;
> + }
> + }
> + return 0;
> +}
> +
> +static int find_duplicated_priority(struct device *dev, void *data)
> +{
> + if (is_typec_altmode(dev)) {
> + struct typec_altmode **alt_target = (struct typec_altmode **)data;
> + struct typec_altmode *alt = to_typec_altmode(dev);
> +
> + if (alt != *alt_target && alt->priority == (*alt_target)->priority)
> + return 1;
> + }
> + return 0;
> +}
> +
> +static int typec_mode_set_priority(struct typec_altmode *alt, const u8 priority)
> +{
> + struct typec_port *port = to_typec_port(alt->dev.parent);
> + const u8 old_priority = alt->priority;
> + int res = 1;
> +
> + alt->priority = priority;
> + while (res) {
> + res = device_for_each_child(&port->dev, &alt, find_duplicated_priority);
> + if (res) {
> + alt->priority++;
> + if (alt->priority == 0) {
> + alt->priority = old_priority;
> + return -EOVERFLOW;
> + }
> + }
> + }
> +
> + res = 1;
> + alt->priority = priority;
> + while (res)
> + res = device_for_each_child(&port->dev, &alt,
> + increment_duplicated_priority);
> +
> + return 0;
> +}
> +
> +static ssize_t priority_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t size)
> +{
> + u8 val;
> + int err = kstrtou8(buf, 10, &val);
> +
> + if (!err)
> + err = typec_mode_set_priority(to_typec_altmode(dev), val);
> +
> + if (!err)
> + return size;
> + return err;
> +}
> +
> +static ssize_t priority_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + return sysfs_emit(buf, "%u\n", to_typec_altmode(dev)->priority);
> +}
> +static DEVICE_ATTR_RW(priority);
> +
> static struct attribute *typec_altmode_attrs[] = {
> &dev_attr_active.attr,
> &dev_attr_mode.attr,
> &dev_attr_svid.attr,
> &dev_attr_vdo.attr,
> + &dev_attr_priority.attr,
> NULL
> };
>
> @@ -459,11 +536,15 @@ static umode_t typec_altmode_attr_is_visible(struct kobject *kobj,
> struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj));
> struct typec_port *port = typec_altmode2port(adev);
>
> - if (attr == &dev_attr_active.attr)
> + if (attr == &dev_attr_active.attr) {
> if (!is_typec_port(adev->dev.parent)) {
> if (!port->mode_control || !adev->ops || !adev->ops->activate)
> return 0444;
> }
> + } else if (attr == &dev_attr_priority.attr) {
> + if (!is_typec_port(adev->dev.parent) || !port->mode_control)
> + return 0;
> + }
>
> return attr->mode;
> }
> @@ -2484,6 +2565,7 @@ typec_port_register_altmode(struct typec_port *port,
> struct typec_altmode *adev;
> struct typec_mux *mux;
> struct typec_retimer *retimer;
> + int ret;
>
> mux = typec_mux_get(&port->dev);
> if (IS_ERR(mux))
> @@ -2502,6 +2584,12 @@ typec_port_register_altmode(struct typec_port *port,
> } else {
> to_altmode(adev)->mux = mux;
> to_altmode(adev)->retimer = retimer;
> +
> + ret = typec_mode_set_priority(adev, 0);
> + if (ret) {
> + typec_unregister_altmode(adev);
> + return ERR_PTR(ret);
> + }
> }
>
> return adev;
> diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
> index f7db3bd4c90e..2c3b6bec2eca 100644
> --- a/include/linux/usb/typec_altmode.h
> +++ b/include/linux/usb/typec_altmode.h
> @@ -28,6 +28,7 @@ struct typec_altmode {
> int mode;
> u32 vdo;
> unsigned int active:1;
> + u8 priority;
>
> char *desc;
> const struct typec_altmode_ops *ops;
> --
> 2.52.0.rc2.455.g230fcf2819-goog
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 0/4] USB Type-C alternate mode priorities
2025-11-24 12:46 [PATCH v5 0/4] USB Type-C alternate mode priorities Andrei Kuchynski
` (3 preceding siblings ...)
2025-11-24 12:46 ` [PATCH v5 4/4] usb: typec: Expose alternate mode priority via sysfs Andrei Kuchynski
@ 2025-11-26 9:23 ` Heikki Krogerus
2025-12-01 8:22 ` Andrei Kuchynski
4 siblings, 1 reply; 12+ messages in thread
From: Heikki Krogerus @ 2025-11-26 9:23 UTC (permalink / raw)
To: Andrei Kuchynski
Cc: Abhishek Pandit-Subedi, Benson Leung, Jameson Thies,
Tzung-Bi Shih, linux-usb, chrome-platform, Guenter Roeck,
Greg Kroah-Hartman, Dmitry Baryshkov, Christian A. Ehrhardt,
Abel Vesa, Pooja Katiyar, Venkat Jayaraman, linux-kernel
Hi Andrei, guys,
Mon, Nov 24, 2025 at 12:46:35PM +0000, Andrei Kuchynski kirjoitti:
> This patch series introduces a mechanism for setting USB Type-C alternate
> mode priorities. It allows the user to specify their preferred order for
> mode selection, such as USB4, Thunderbolt, or DisplayPort.
>
> A new sysfs attribute named 'priority' is exposed to provide user-space
> control over the mode selection process.
>
> This series was tested on a Android OS device running kernel 6.18.0-rc6.
>
> Changes in v5:
> - Patches 3 and 4 (v4) have been consolidated into a singular patch,
> keeping the mode priority implementation within drivers/usb/typec/class.c.
>
> Andrei Kuchynski (4):
> usb: typec: Add mode_control field to port property
> platform/chrome: cros_ec_typec: Set no_mode_control flag
> usb: typec: ucsi: Set no_mode_control flag
> usb: typec: Expose alternate mode priority via sysfs
>
> Documentation/ABI/testing/sysfs-class-typec | 11 +++
> drivers/platform/chrome/cros_ec_typec.c | 1 +
> drivers/usb/typec/class.c | 99 ++++++++++++++++++++-
> drivers/usb/typec/class.h | 1 +
> drivers/usb/typec/ucsi/ucsi.c | 1 +
> include/linux/usb/typec.h | 2 +
> include/linux/usb/typec_altmode.h | 1 +
> 7 files changed, 112 insertions(+), 4 deletions(-)
These are okay by me. I think we can move to the next step. But I'm
not sure we apply these before that, because the file has no effect
at the moment.
Br,
--
heikki
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH v5 0/4] USB Type-C alternate mode priorities
2025-11-26 9:23 ` [PATCH v5 0/4] USB Type-C alternate mode priorities Heikki Krogerus
@ 2025-12-01 8:22 ` Andrei Kuchynski
0 siblings, 0 replies; 12+ messages in thread
From: Andrei Kuchynski @ 2025-12-01 8:22 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Abhishek Pandit-Subedi, Benson Leung, Jameson Thies,
Tzung-Bi Shih, linux-usb, chrome-platform, Guenter Roeck,
Greg Kroah-Hartman, Dmitry Baryshkov, Christian A. Ehrhardt,
Abel Vesa, Pooja Katiyar, Venkat Jayaraman, linux-kernel
On Wed, Nov 26, 2025 at 10:23 AM Heikki Krogerus
<heikki.krogerus@linux.intel.com> wrote:
>
> Hi Andrei, guys,
>
> Mon, Nov 24, 2025 at 12:46:35PM +0000, Andrei Kuchynski kirjoitti:
> > This patch series introduces a mechanism for setting USB Type-C alternate
> > mode priorities. It allows the user to specify their preferred order for
> > mode selection, such as USB4, Thunderbolt, or DisplayPort.
> >
> > A new sysfs attribute named 'priority' is exposed to provide user-space
> > control over the mode selection process.
> >
> > This series was tested on a Android OS device running kernel 6.18.0-rc6.
> >
> > Changes in v5:
> > - Patches 3 and 4 (v4) have been consolidated into a singular patch,
> > keeping the mode priority implementation within drivers/usb/typec/class.c.
> >
> > Andrei Kuchynski (4):
> > usb: typec: Add mode_control field to port property
> > platform/chrome: cros_ec_typec: Set no_mode_control flag
> > usb: typec: ucsi: Set no_mode_control flag
> > usb: typec: Expose alternate mode priority via sysfs
> >
> > Documentation/ABI/testing/sysfs-class-typec | 11 +++
> > drivers/platform/chrome/cros_ec_typec.c | 1 +
> > drivers/usb/typec/class.c | 99 ++++++++++++++++++++-
> > drivers/usb/typec/class.h | 1 +
> > drivers/usb/typec/ucsi/ucsi.c | 1 +
> > include/linux/usb/typec.h | 2 +
> > include/linux/usb/typec_altmode.h | 1 +
> > 7 files changed, 112 insertions(+), 4 deletions(-)
>
> These are okay by me. I think we can move to the next step. But I'm
> not sure we apply these before that, because the file has no effect
> at the moment.
>
> Br,
>
> --
> heikki
Hi Heikki, Abel, Benson,
Thank you for your review of the series.
I will send the subsequent series detailing how we are going to use
priorities in cros_ec_typec and cros_ec_ucsi drivers.
Thanks,
Andrei
^ permalink raw reply [flat|nested] 12+ messages in thread