All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benson Leung <bleung@google.com>
To: Andrei Kuchynski <akuchynski@chromium.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Abhishek Pandit-Subedi <abhishekpandit@chromium.org>,
	Benson Leung <bleung@chromium.org>,
	Jameson Thies <jthies@google.com>,
	Tzung-Bi Shih <tzungbi@kernel.org>,
	linux-usb@vger.kernel.org, chrome-platform@lists.linux.dev,
	Guenter Roeck <groeck@chromium.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>,
	"Christian A. Ehrhardt" <lk@c--e.de>,
	Abel Vesa <abel.vesa@linaro.org>,
	Pooja Katiyar <pooja.katiyar@intel.com>,
	Venkat Jayaraman <venkat.jayaraman@intel.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v5 4/4] usb: typec: Expose alternate mode priority via sysfs
Date: Tue, 25 Nov 2025 00:20:23 +0000	[thread overview]
Message-ID: <aST2RyOIjHiTv6J3@google.com> (raw)
In-Reply-To: <20251124124639.1101335-5-akuchynski@chromium.org>

[-- 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 --]

  parent reply	other threads:[~2025-11-25  0:20 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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-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
2025-11-25  0:15   ` Benson Leung
2025-11-24 12:46 ` [PATCH v5 3/4] usb: typec: ucsi: " 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-24 14:25   ` Abel Vesa
2025-11-25  0:20   ` Benson Leung [this message]
2025-11-26  9:23 ` [PATCH v5 0/4] USB Type-C alternate mode priorities Heikki Krogerus
2025-12-01  8:22   ` Andrei Kuchynski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aST2RyOIjHiTv6J3@google.com \
    --to=bleung@google.com \
    --cc=abel.vesa@linaro.org \
    --cc=abhishekpandit@chromium.org \
    --cc=akuchynski@chromium.org \
    --cc=bleung@chromium.org \
    --cc=chrome-platform@lists.linux.dev \
    --cc=dmitry.baryshkov@oss.qualcomm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=groeck@chromium.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=jthies@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=lk@c--e.de \
    --cc=pooja.katiyar@intel.com \
    --cc=tzungbi@kernel.org \
    --cc=venkat.jayaraman@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.