summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Vasut <marex@nabladev.com>2026-08-22 09:24:58 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-09-01 16:31:39 +0200
commitd50b6442bef66abbe4694f918f8ad013f81d75cf (patch)
tree1f1e2babbb258370f8919d86ff0b30e65231906a
parentdea99705bc8fcda12590cfeeae6d2ba47a7ef572 (diff)
downloadlinux-d50b6442bef66abbe4694f918f8ad013f81d75cf.tar.gz
linux-d50b6442bef66abbe4694f918f8ad013f81d75cf.zip
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 <stable@kernel.org> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> Co-developed-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Marek Vasut <marex@nabladev.com> Tested-by: Jens Glathe <jens.glathe@oldschoolsolutions.biz> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Link: https://patch.msgid.link/20260822072556.490594-1-marex@nabladev.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/typec/mux.c17
1 files 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) {