From d50b6442bef66abbe4694f918f8ad013f81d75cf Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 22 Aug 2026 09:24:58 +0200 Subject: [PATCH] usb: typec: mux: avoid duplicated mux switches 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. This is a re-application of b145c3f29d62 ("usb: typec: mux: avoid duplicated mux switches"), with fix derived from usb: typec: mux: Fix typec_switch_match() . Fixes: f576c75f95a5 ("Revert "usb: typec: mux: avoid duplicated mux switches"") Cc: stable Signed-off-by: Sebastian Reichel Co-developed-by: Sebastian Reichel Signed-off-by: Marek Vasut Tested-by: Jens Glathe Reviewed-by: Heikki Krogerus Link: https://patch.msgid.link/20260822072556.490594-1-marex@nabladev.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/mux.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 2bc7e8edb3cb..afa6fc181397 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -277,7 +277,9 @@ static int mux_fwnode_match(struct device *dev, const void *fwnode) static void *typec_mux_match(const struct fwnode_handle *fwnode, const char *id, void *data) { + struct typec_mux_dev **mux_devs = data; struct device *dev; + int i; /* * Device graph (OF graph) does not give any means to identify the @@ -292,8 +294,18 @@ static void *typec_mux_match(const struct fwnode_handle *fwnode, dev = class_find_device(&typec_mux_class, NULL, fwnode, mux_fwnode_match); + if (!dev) + return ERR_PTR(-EPROBE_DEFER); - return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER); + /* Skip duplicates */ + for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++) + if (to_typec_mux_dev(dev) == mux_devs[i]) { + put_device(dev); + return NULL; + } + + + return to_typec_mux_dev(dev); } /** @@ -318,7 +330,8 @@ struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode) return ERR_PTR(-ENOMEM); count = fwnode_connection_find_matches(fwnode, "mode-switch", - NULL, typec_mux_match, + (void **)mux_devs, + typec_mux_match, (void **)mux_devs, ARRAY_SIZE(mux_devs)); if (count <= 0) {