Re: [PATCH v2 4/5] usb: typec: Implement alternate mode priority handling
From: Andrei Kuchynski <akuchynski@chromium.org>
Date: 2025-09-05 11:59:14
Also in:
chrome-platform, lkml
On Fri, Sep 5, 2025 at 12:25 PM Heikki Krogerus [off-list ref] wrote:
On Mon, Aug 25, 2025 at 02:57:49PM +0000, Andrei Kuchynski wrote:quoted
This patch introduces APIs to manage the priority of USB Type-C alternate modes. These APIs allow for setting and retrieving a priority number for each mode. 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> --- drivers/usb/typec/Makefile | 2 +- drivers/usb/typec/mode_selection.c | 38 ++++++++++++++++++++++++++++++ drivers/usb/typec/mode_selection.h | 6 +++++ include/linux/usb/typec_altmode.h | 1 + 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/typec/mode_selection.c create mode 100644 drivers/usb/typec/mode_selection.hdiff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile index 7a368fea61bc..8a6a1c663eb6 100644 --- a/drivers/usb/typec/Makefile +++ b/drivers/usb/typec/Makefile@@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TYPEC) += typec.o -typec-y := class.o mux.o bus.o pd.o retimer.o +typec-y := class.o mux.o bus.o pd.o retimer.o mode_selection.o typec-$(CONFIG_ACPI) += port-mapper.o obj-$(CONFIG_TYPEC) += altmodes/ obj-$(CONFIG_TYPEC_TCPM) += tcpm/diff --git a/drivers/usb/typec/mode_selection.c b/drivers/usb/typec/mode_selection.c new file mode 100644 index 000000000000..2179bf25f5d4 --- /dev/null +++ b/drivers/usb/typec/mode_selection.c@@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2025 Google LLC. + */ + +#include "mode_selection.h" +#include "class.h" +#include "bus.h" + +static int increment_duplicated_priority(struct device *dev, void *data) +{ + struct typec_altmode **alt_target = (struct typec_altmode **)data; + + if (is_typec_altmode(dev)) { + struct typec_altmode *alt = to_typec_altmode(dev); + + if (alt != *alt_target && alt->priority == (*alt_target)->priority) { + alt->priority++; + *alt_target = alt; + return 1;Couldn't you just always return 0?
Priority values for each mode are consistently unique, eliminating the need for further processing if a duplicate is found.
quoted
+ } + } + + return 0; +} + +void typec_mode_set_priority(struct typec_altmode *alt, + const unsigned int priority) +{ + struct typec_port *port = to_typec_port(alt->dev.parent); + int res = 1; + + alt->priority = priority; + + while (res) + res = device_for_each_child(&port->dev, &alt, + increment_duplicated_priority);Then this could be: device_for_each_child(&port->dev, &alt, increment_duplicated_priority); right?
Unfortunately, the child's list is not in prioritized order. When a duplicated value is found, the cycle should start for the whole list again. I definitely need a loop here. Thanks, Andrei