* [PATCH 0/2] usb: typec: mux: avoid duplicated mux switches
@ 2026-02-13 19:23 Sebastian Reichel
2026-02-13 19:23 ` [PATCH 1/2] usb: typec: mux: avoid duplicated orientation switches Sebastian Reichel
2026-02-13 19:23 ` [PATCH 2/2] usb: typec: mux: avoid duplicated mux switches Sebastian Reichel
0 siblings, 2 replies; 5+ messages in thread
From: Sebastian Reichel @ 2026-02-13 19:23 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman
Cc: linux-rockchip, linux-usb, linux-kernel, kernel,
Sebastian Reichel
Recent Rockchip SoCs (e.g. RK3588, RK3576) have a PHY, which
handles USB3 and DisplayPort as well as orientation and lane
muxing. By setting up the DT graph from the USB-C connector
for the Superspeed and DP lanes to the PHY all mux/orientation
operations are applied twice.
I did not add any Fixes tag, since applying the settings twice
is not breaking anything. But it's confusing when debugging
USB-C issues and obviously wastes some CPU cycles.
Also I'm not super happy with the implementation I came up with
to do the actual duplicate elimination. In the end I figured
it does not matter to much considering the array size is 3 and
is not expected to become much bigger as the amount of muxes
on a single USB-C connector should be quite low :)
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
Sebastian Reichel (2):
usb: typec: mux: avoid duplicated orientation switches
usb: typec: mux: avoid duplicated mux switches
drivers/usb/typec/mux.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
---
base-commit: 05f7e89ab9731565d8a62e3b5d1ec206485eeb0b
change-id: 20260213-typec-mux-duplication-fix-ba5e58f6576a
Best regards,
--
Sebastian Reichel <sebastian.reichel@collabora.com>
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 1/2] usb: typec: mux: avoid duplicated orientation switches 2026-02-13 19:23 [PATCH 0/2] usb: typec: mux: avoid duplicated mux switches Sebastian Reichel @ 2026-02-13 19:23 ` Sebastian Reichel 2026-02-23 14:54 ` Heikki Krogerus 2026-02-13 19:23 ` [PATCH 2/2] usb: typec: mux: avoid duplicated mux switches Sebastian Reichel 1 sibling, 1 reply; 5+ messages in thread From: Sebastian Reichel @ 2026-02-13 19:23 UTC (permalink / raw) To: Heikki Krogerus, Greg Kroah-Hartman Cc: linux-rockchip, linux-usb, linux-kernel, kernel, Sebastian Reichel Some devices use combo PHYs (i.e. USB3 + DisplayPort), which also handle the orientation mux. These PHYs are referenced twice from the USB-C connector (USB super-speed lines and SBU/AUX lines) resulting in the switch being configured twice. Avoid this by dropping duplicates. Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> --- drivers/usb/typec/mux.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 182c902c42f6..db35b7398343 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -72,9 +72,9 @@ struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode) { struct typec_switch_dev *sw_devs[TYPEC_MUX_MAX_DEVS]; struct typec_switch *sw; + int i, j, k; int count; int err; - int i; sw = kzalloc(sizeof(*sw), GFP_KERNEL); if (!sw) @@ -96,6 +96,18 @@ struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode) } } + /* eliminate duplicates */ + for (i = 0; i < count; i++) { + for (j = i + 1; j < count; j++) { + if (sw_devs[j] == sw_devs[i]) { + put_device(&sw_devs[j]->dev); + for (k = j; k < count; k++) + sw_devs[k] = sw_devs[k+1]; + count--; + } + } + } + for (i = 0; i < count; i++) { WARN_ON(!try_module_get(sw_devs[i]->dev.parent->driver->owner)); sw->sw_devs[i] = sw_devs[i]; -- 2.51.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] usb: typec: mux: avoid duplicated orientation switches 2026-02-13 19:23 ` [PATCH 1/2] usb: typec: mux: avoid duplicated orientation switches Sebastian Reichel @ 2026-02-23 14:54 ` Heikki Krogerus 0 siblings, 0 replies; 5+ messages in thread From: Heikki Krogerus @ 2026-02-23 14:54 UTC (permalink / raw) To: Sebastian Reichel Cc: Greg Kroah-Hartman, linux-rockchip, linux-usb, linux-kernel, kernel Hi Sebastian, Fri, Feb 13, 2026 at 08:23:28PM +0100, Sebastian Reichel wrote: > Some devices use combo PHYs (i.e. USB3 + DisplayPort), which also > handle the orientation mux. These PHYs are referenced twice from > the USB-C connector (USB super-speed lines and SBU/AUX lines) > resulting in the switch being configured twice. Avoid this by > dropping duplicates. > > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> > --- > drivers/usb/typec/mux.c | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c > index 182c902c42f6..db35b7398343 100644 > --- a/drivers/usb/typec/mux.c > +++ b/drivers/usb/typec/mux.c > @@ -72,9 +72,9 @@ struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode) > { > struct typec_switch_dev *sw_devs[TYPEC_MUX_MAX_DEVS]; > struct typec_switch *sw; > + int i, j, k; > int count; > int err; > - int i; > > sw = kzalloc(sizeof(*sw), GFP_KERNEL); > if (!sw) > @@ -96,6 +96,18 @@ struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode) > } > } > > + /* eliminate duplicates */ > + for (i = 0; i < count; i++) { > + for (j = i + 1; j < count; j++) { > + if (sw_devs[j] == sw_devs[i]) { > + put_device(&sw_devs[j]->dev); > + for (k = j; k < count; k++) > + sw_devs[k] = sw_devs[k+1]; > + count--; > + } > + } > + } I think that check could be done in typec_switch_match(). Just pass that sw_devs to it as "data": - count = fwnode_connection_find_matches(fwnode, "orientation-switch", NULL, + count = fwnode_connection_find_matches(fwnode, "orientation-switch", sw_devs, And then in typec_switch_match(), probable as the second last step: static void *typec_switch_match(const struct fwnode_handle *fwnode, const char *id, void *data) { + struct typec_switch_dev *sw_devs = data; + int i; ... dev = class_find_device(&typec_mux_class, NULL, fwnode, switch_fwnode_match); + /* Skip duplicates */ + for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++) + if (to_typec_switch_dev(dev) == sw_devs[i]) { + put_device(dev); + return NULL; + } return dev ? to_typec_switch_dev(dev) : ERR_PTR(-EPROBE_DEFER); } thanks, -- heikki ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] usb: typec: mux: avoid duplicated mux switches 2026-02-13 19:23 [PATCH 0/2] usb: typec: mux: avoid duplicated mux switches Sebastian Reichel 2026-02-13 19:23 ` [PATCH 1/2] usb: typec: mux: avoid duplicated orientation switches Sebastian Reichel @ 2026-02-13 19:23 ` Sebastian Reichel 2026-02-23 15:02 ` Heikki Krogerus 1 sibling, 1 reply; 5+ messages in thread From: Sebastian Reichel @ 2026-02-13 19:23 UTC (permalink / raw) To: Heikki Krogerus, Greg Kroah-Hartman Cc: linux-rockchip, linux-usb, linux-kernel, kernel, Sebastian Reichel Some devices use combo PHYs (i.e. USB3 + DisplayPort), which also handle the lane muxing. These PHYs are referenced twice from the USB-C connector (USB super-speed lines and SBU/AUX lines) resulting in the mux being configured twice. Avoid this by dropping duplicates. Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> --- drivers/usb/typec/mux.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index db35b7398343..6a394326f236 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -309,9 +309,9 @@ struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode) { struct typec_mux_dev *mux_devs[TYPEC_MUX_MAX_DEVS]; struct typec_mux *mux; + int i, j, k; int count; int err; - int i; mux = kzalloc(sizeof(*mux), GFP_KERNEL); if (!mux) @@ -333,6 +333,18 @@ struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode) } } + /* eliminate duplicates */ + for (i = 0; i < count; i++) { + for (j = i + 1; j < count; j++) { + if (mux_devs[j] == mux_devs[i]) { + put_device(&mux_devs[j]->dev); + for (k = j; k < count; k++) + mux_devs[k] = mux_devs[k+1]; + count--; + } + } + } + for (i = 0; i < count; i++) { WARN_ON(!try_module_get(mux_devs[i]->dev.parent->driver->owner)); mux->mux_devs[i] = mux_devs[i]; -- 2.51.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] usb: typec: mux: avoid duplicated mux switches 2026-02-13 19:23 ` [PATCH 2/2] usb: typec: mux: avoid duplicated mux switches Sebastian Reichel @ 2026-02-23 15:02 ` Heikki Krogerus 0 siblings, 0 replies; 5+ messages in thread From: Heikki Krogerus @ 2026-02-23 15:02 UTC (permalink / raw) To: Sebastian Reichel Cc: Greg Kroah-Hartman, linux-rockchip, linux-usb, linux-kernel, kernel Fri, Feb 13, 2026 at 08:23:29PM +0100, Sebastian Reichel wrote: > Some devices use combo PHYs (i.e. USB3 + DisplayPort), which also > handle the lane muxing. These PHYs are referenced twice from > the USB-C connector (USB super-speed lines and SBU/AUX lines) > resulting in the mux being configured twice. Avoid this by > dropping duplicates. > > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> > --- > drivers/usb/typec/mux.c | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c > index db35b7398343..6a394326f236 100644 > --- a/drivers/usb/typec/mux.c > +++ b/drivers/usb/typec/mux.c > @@ -309,9 +309,9 @@ struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode) > { > struct typec_mux_dev *mux_devs[TYPEC_MUX_MAX_DEVS]; > struct typec_mux *mux; > + int i, j, k; > int count; > int err; > - int i; > > mux = kzalloc(sizeof(*mux), GFP_KERNEL); > if (!mux) > @@ -333,6 +333,18 @@ struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode) > } > } > > + /* eliminate duplicates */ > + for (i = 0; i < count; i++) { > + for (j = i + 1; j < count; j++) { > + if (mux_devs[j] == mux_devs[i]) { > + put_device(&mux_devs[j]->dev); > + for (k = j; k < count; k++) > + mux_devs[k] = mux_devs[k+1]; > + count--; > + } > + } > + } The same should work here. My code snippets probable has to be modified, but the idea should work. The check should be more simple to do in typec_switch_match(). Br, -- heikki ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-02-23 15:02 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-13 19:23 [PATCH 0/2] usb: typec: mux: avoid duplicated mux switches Sebastian Reichel 2026-02-13 19:23 ` [PATCH 1/2] usb: typec: mux: avoid duplicated orientation switches Sebastian Reichel 2026-02-23 14:54 ` Heikki Krogerus 2026-02-13 19:23 ` [PATCH 2/2] usb: typec: mux: avoid duplicated mux switches Sebastian Reichel 2026-02-23 15:02 ` Heikki Krogerus
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox