* [PATCH v2 0/3] Restrict alternate modes based on cable capabilities
@ 2026-06-22 9:39 Andrei Kuchynski
2026-06-22 9:39 ` [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support Andrei Kuchynski
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Andrei Kuchynski @ 2026-06-22 9:39 UTC (permalink / raw)
To: Heikki Krogerus, Benson Leung, Jameson Thies
Cc: Greg Kroah-Hartman, linux-usb, linux-kernel, Andrei Kuchynski
Currently, alternate mode drivers (like DisplayPort and Thunderbolt)
automatically assign operational callbacks (`typec_altmode_set_ops`)
during probing, even if the underlying cable capabilities cannot support
them. This can lead to incorrectly advertised state configurations or
initialization failures later on.
The first patch introduces the core helper function, and the subsequent
patches update the DisplayPort and Thunderbolt altmode drivers to
utilize this check during their respective probe phases.
Changes in v2:
- Updated patch 1/3 to use a switch-case statement, added detailed inline
comments, and separated the non-e-marked cable validation logic.
- Patches 2 and 3 remain unchanged from the previous version.
Andrei Kuchynski (3):
usb: typec: Add helper to check cable altmode support
usb: typec: thunderbolt: Check cable altmode support
usb: typec: displayport: Check cable altmode support
drivers/usb/typec/altmodes/displayport.c | 5 +-
drivers/usb/typec/altmodes/thunderbolt.c | 4 ++
drivers/usb/typec/class.c | 65 ++++++++++++++++++++++++
include/linux/usb/typec.h | 1 +
4 files changed, 74 insertions(+), 1 deletion(-)
--
2.55.0.rc0.738.g0c8ab3ebcc-goog
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support 2026-06-22 9:39 [PATCH v2 0/3] Restrict alternate modes based on cable capabilities Andrei Kuchynski @ 2026-06-22 9:39 ` Andrei Kuchynski 2026-06-22 10:18 ` Heikki Krogerus 2026-06-22 9:39 ` [PATCH v2 2/3] usb: typec: thunderbolt: Check " Andrei Kuchynski 2026-06-22 9:39 ` [PATCH v2 3/3] usb: typec: displayport: " Andrei Kuchynski 2 siblings, 1 reply; 7+ messages in thread From: Andrei Kuchynski @ 2026-06-22 9:39 UTC (permalink / raw) To: Heikki Krogerus, Benson Leung, Jameson Thies Cc: Greg Kroah-Hartman, linux-usb, linux-kernel, Andrei Kuchynski Introduce typec_cable_altmode_unsupported function to evaluate whether an alternate mode is restricted based on the connected cable's properties. Implement validation logic that parses the cable's identity to catch incompatible setups early. Alternate modes are restricted over: - cables lacking an identity header - passive cables with USB 2.0 speed - active cables unless they have corresponding plugs The function returns false if the cable is not registered or the identifier is not set. Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org> --- Changes in V2: - Replaced the if/else chain with a switch-case block. - Added detailed inline comments explaining the USB PD cable specification constraints. - Separated the check for non-e-marked cables. drivers/usb/typec/class.c | 65 +++++++++++++++++++++++++++++++++++++++ include/linux/usb/typec.h | 1 + 2 files changed, 66 insertions(+) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 0977581ad1b6e..972c870e3ce51 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1429,6 +1429,71 @@ int typec_cable_is_active(struct typec_cable *cable) } EXPORT_SYMBOL_GPL(typec_cable_is_active); +/** + * typec_cable_altmode_unsupported - Check if a cable restricts altmode + * @alt: The Alternate Mode to evaluate + * + * Returns true if the connected cable is incapable of handling the altmode. + */ +bool typec_cable_altmode_unsupported(struct typec_altmode *alt) +{ + struct typec_altmode *plug; + struct typec_cable *cable; + bool unsupported = false; + + /* + * Check if the cable has an e-marker, supports modal operation, and the + * SOP' altmode nodes are created. If yes, then altmode is supported. + */ + plug = typec_altmode_get_plug(alt, TYPEC_PLUG_SOP_P); + if (plug) { + typec_altmode_put_plug(plug); + return false; + } + + /* + * Check if the cable is registered and its identity is specified. + * If not, the cable altmode restriction cannot be checked. + */ + cable = typec_cable_get(typec_altmode2port(alt)); + if (cable && cable->identity) { + const u32 id_header = cable->identity->id_header; + const u32 speed = VDO_TYPEC_CABLE_SPEED(cable->identity->vdo[0]); + + /* + * A cable lacking an ID Header indicates a non-e-marked cable, + * can only be guaranteed to have a USB 2.0 data path (D+ and D-). + */ + if (!id_header) { + unsupported = true; + } else { + switch (PD_IDH_PTYPE(id_header)) { + /* + * If the speed field explicitly declares it is a + * USB 2.0-only cable, altmode is unsupported. + */ + case IDH_PTYPE_PCABLE: + unsupported = (speed == CABLE_USB2_ONLY); + break; + /* + * Active cables must establish an SOP' communication + * node. Since that check failed at the beginning of + * this function, this active cable does not support + * this specific altmode. + */ + case IDH_PTYPE_ACABLE: + unsupported = true; + break; + } + } + } + if (cable) + typec_cable_put(cable); + + return unsupported; +} +EXPORT_SYMBOL_GPL(typec_cable_altmode_unsupported); + /** * typec_cable_set_identity - Report result from Discover Identity command * @cable: The cable updated identity values diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index d61ec38216fa9..10a783b738efd 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -337,6 +337,7 @@ void typec_unregister_cable(struct typec_cable *cable); struct typec_cable *typec_cable_get(struct typec_port *port); void typec_cable_put(struct typec_cable *cable); int typec_cable_is_active(struct typec_cable *cable); +bool typec_cable_altmode_unsupported(struct typec_altmode *alt); struct typec_plug *typec_register_plug(struct typec_cable *cable, struct typec_plug_desc *desc); -- 2.55.0.rc0.738.g0c8ab3ebcc-goog ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support 2026-06-22 9:39 ` [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support Andrei Kuchynski @ 2026-06-22 10:18 ` Heikki Krogerus 2026-06-22 12:03 ` Andrei Kuchynski 0 siblings, 1 reply; 7+ messages in thread From: Heikki Krogerus @ 2026-06-22 10:18 UTC (permalink / raw) To: Andrei Kuchynski Cc: Benson Leung, Jameson Thies, Greg Kroah-Hartman, linux-usb, linux-kernel Hi Andrei, > +bool typec_cable_altmode_unsupported(struct typec_altmode *alt) > +{ > + struct typec_altmode *plug; > + struct typec_cable *cable; > + bool unsupported = false; > + > + /* > + * Check if the cable has an e-marker, supports modal operation, and the > + * SOP' altmode nodes are created. If yes, then altmode is supported. > + */ > + plug = typec_altmode_get_plug(alt, TYPEC_PLUG_SOP_P); > + if (plug) { > + typec_altmode_put_plug(plug); > + return false; > + } > + > + /* > + * Check if the cable is registered and its identity is specified. > + * If not, the cable altmode restriction cannot be checked. > + */ > + cable = typec_cable_get(typec_altmode2port(alt)); > + if (cable && cable->identity) { > + const u32 id_header = cable->identity->id_header; > + const u32 speed = VDO_TYPEC_CABLE_SPEED(cable->identity->vdo[0]); > + > + /* > + * A cable lacking an ID Header indicates a non-e-marked cable, > + * can only be guaranteed to have a USB 2.0 data path (D+ and D-). > + */ > + if (!id_header) { > + unsupported = true; > + } else { > + switch (PD_IDH_PTYPE(id_header)) { > + /* > + * If the speed field explicitly declares it is a > + * USB 2.0-only cable, altmode is unsupported. > + */ > + case IDH_PTYPE_PCABLE: > + unsupported = (speed == CABLE_USB2_ONLY); > + break; > + /* > + * Active cables must establish an SOP' communication > + * node. Since that check failed at the beginning of > + * this function, this active cable does not support > + * this specific altmode. > + */ > + case IDH_PTYPE_ACABLE: > + unsupported = true; > + break; > + } > + } > + } > + if (cable) > + typec_cable_put(cable); > + > + return unsupported; So if typec_cable_get() doesn't return a cable, this function will now always return false - i.e. the cable is supported? Is that intentional? This would probable be much more clear if you checked the cable only ones, right after you take the handle. cable = typec_cable_get(typec_altmode2port(alt)); if (!cable) return true; /* or false? */ ... /* Now unconditionally */ typec_cable_put(cable); I think this would be even more clear if the function was called typec_cable_altmode_supported() and you would then have a wrapper: static inline bool typec_cable_altmode_unsupported(struct typec_altmode *alt) { return !typec_cable_altmode_supported(alt); } Thanks, -- heikki ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support 2026-06-22 10:18 ` Heikki Krogerus @ 2026-06-22 12:03 ` Andrei Kuchynski 2026-06-23 8:30 ` Heikki Krogerus 0 siblings, 1 reply; 7+ messages in thread From: Andrei Kuchynski @ 2026-06-22 12:03 UTC (permalink / raw) To: Heikki Krogerus Cc: Benson Leung, Jameson Thies, Greg Kroah-Hartman, linux-usb, linux-kernel Hi Heikki, On Mon, Jun 22, 2026 at 12:18 PM Heikki Krogerus <heikki.krogerus@linux.intel.com> wrote: > > Hi Andrei, > > > +bool typec_cable_altmode_unsupported(struct typec_altmode *alt) > > +{ > > + return unsupported; > > So if typec_cable_get() doesn't return a cable, this function will now > always return false - i.e. the cable is supported? Is that intentional? > Yes, this is intentional. The UCSI GET_CABLE_PROPERTY command is optional. typec_register_cable() function can also be called without the desc->identity field. Failing to provide cable information shouldn't be a reason to reject the alternate mode. Also, the cable can be registered after the partner's altmodes. We encounter this scenario with the cros_ec_typec driver. I'm planning to fix it, but for now, this approach will preserve the previous behavior. Therefore, the idea is to reject the altmode only if we know the cable doesn't support it. That's why the function is called "unsupported". It returns true if a limitation is detected. Otherwise, the function returns false. > This would probable be much more clear if you checked the cable only > ones, right after you take the handle. > > cable = typec_cable_get(typec_altmode2port(alt)); > if (!cable) > return true; /* or false? */ > ... > /* Now unconditionally */ > typec_cable_put(cable); > Ok, I'll redo it. Thanks > I think this would be even more clear if the function was called > typec_cable_altmode_supported() and you would then have a wrapper: > > static inline bool typec_cable_altmode_unsupported(struct typec_altmode *alt) > { > return !typec_cable_altmode_supported(alt); > } > I prefer exporting the 'unsupported' helper to altmode drivers. While its naming is slightly less intuitive, it accurately reflects the logic. What do you think about it? Thanks, Andrei ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support 2026-06-22 12:03 ` Andrei Kuchynski @ 2026-06-23 8:30 ` Heikki Krogerus 0 siblings, 0 replies; 7+ messages in thread From: Heikki Krogerus @ 2026-06-23 8:30 UTC (permalink / raw) To: Andrei Kuchynski Cc: Benson Leung, Jameson Thies, Greg Kroah-Hartman, linux-usb, linux-kernel On Mon, Jun 22, 2026 at 02:03:48PM +0200, Andrei Kuchynski wrote: > Hi Heikki, > > On Mon, Jun 22, 2026 at 12:18 PM Heikki Krogerus > <heikki.krogerus@linux.intel.com> wrote: > > > > Hi Andrei, > > > > > +bool typec_cable_altmode_unsupported(struct typec_altmode *alt) > > > +{ > > > + return unsupported; > > > > So if typec_cable_get() doesn't return a cable, this function will now > > always return false - i.e. the cable is supported? Is that intentional? > > > > Yes, this is intentional. > The UCSI GET_CABLE_PROPERTY command is optional. typec_register_cable() > function can also be called without the desc->identity field. > Failing to provide cable information shouldn't be a reason to reject the > alternate mode. > Also, the cable can be registered after the partner's altmodes. We > encounter this scenario with the cros_ec_typec driver. I'm planning to fix > it, but for now, this approach will preserve the previous behavior. > > Therefore, the idea is to reject the altmode only if we know the cable > doesn't support it. That's why the function is called "unsupported". > It returns true if a limitation is detected. Otherwise, the function > returns false. One day and I'm completely confused again :). I opened the code for myself (not compiled) to get the idea again. Please consider that, or something like it - the important part for me is the enum. The enum does not cost that many lines, but it does make the idea more clear, at least for me. enum typec_cable_altmode_support { CABLE_SUPPORT_UNKNOWN, CABLE_SUPPORTED, CABLE_NOT_SUPPORTED, }; static enum typec_cable_altmode_support typec_cable_check_altmode_support(struct typec_cable *cable, struct typec_altmode *alt) { struct typec_altmode *plug; const u32 speed; plug = typec_altmode_get_plug(alt); if (plug) { typec_altmode_put_plug(plug); return CABLE_SUPPORTED; } /* Maybe UCSI, or the something else, does no supply the identity */ if (!cable->identity) return ALTMODE_SUPPORT_UNKNOWN; /* Non-e-marked cable */ if (!cable->identity->id_header) return CABLE_NOT_SUPPORTED; speed = VDO_TYPEC_CABLE_SPEED(cable->identity->vdo[0]); switch (PD_IDH_PTYPE(cable->identity->id_header)) { case IDH_PTYPE_PCABLE: if (speed == CABLE_USB2_ONLY) return CABLE_NOT_SUPPORTED; break; case IDH_PTYPE_ACABLE: /* * Active cables must establish an SOP' communication * node. Since that check failed at the beginning of * this function, this active cable does not support * this specific altmode. */ return CABLE_NOT_SUPPORTED; default: break; } return CABLE_SUPPORT_UNKNOWN; } bool typec_altmode_cable_not_supported(struct typec_altmode *alt) { enum typec_cable_altmode_support support = CABLE_SUPPORT_UNKNOWN; struct typec_cable *cable; cable = typec_cable_get(typec_altmode2port(alt)); if (cable) { support = typec_cable_check_altmode_support(cable, alt); typec_cable_put(cable); } return support == CABLE_NOT_SUPPORTED; } thanks, -- heikki ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/3] usb: typec: thunderbolt: Check cable altmode support 2026-06-22 9:39 [PATCH v2 0/3] Restrict alternate modes based on cable capabilities Andrei Kuchynski 2026-06-22 9:39 ` [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support Andrei Kuchynski @ 2026-06-22 9:39 ` Andrei Kuchynski 2026-06-22 9:39 ` [PATCH v2 3/3] usb: typec: displayport: " Andrei Kuchynski 2 siblings, 0 replies; 7+ messages in thread From: Andrei Kuchynski @ 2026-06-22 9:39 UTC (permalink / raw) To: Heikki Krogerus, Benson Leung, Jameson Thies Cc: Greg Kroah-Hartman, linux-usb, linux-kernel, Andrei Kuchynski Update the probe function to utilize the new typec_cable_altmode_unsupported() helper. If the cable doesn't support Thunderbolt altmode, don't initialize altmode_ops and prevent altmode from being activated. Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org> Reviewed-by: Benson Leung <bleung@chromium.org> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> --- drivers/usb/typec/altmodes/thunderbolt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/typec/altmodes/thunderbolt.c b/drivers/usb/typec/altmodes/thunderbolt.c index 32250b94262a9..2eccdddf1b1f4 100644 --- a/drivers/usb/typec/altmodes/thunderbolt.c +++ b/drivers/usb/typec/altmodes/thunderbolt.c @@ -284,6 +284,10 @@ static int tbt_altmode_probe(struct typec_altmode *alt) alt->desc = "Thunderbolt3"; typec_altmode_set_drvdata(alt, tbt); + + if (typec_cable_altmode_unsupported(alt)) + return 0; + typec_altmode_set_ops(alt, &tbt_altmode_ops); if (!alt->mode_selection && tbt_ready(alt)) { -- 2.55.0.rc0.738.g0c8ab3ebcc-goog ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/3] usb: typec: displayport: Check cable altmode support 2026-06-22 9:39 [PATCH v2 0/3] Restrict alternate modes based on cable capabilities Andrei Kuchynski 2026-06-22 9:39 ` [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support Andrei Kuchynski 2026-06-22 9:39 ` [PATCH v2 2/3] usb: typec: thunderbolt: Check " Andrei Kuchynski @ 2026-06-22 9:39 ` Andrei Kuchynski 2 siblings, 0 replies; 7+ messages in thread From: Andrei Kuchynski @ 2026-06-22 9:39 UTC (permalink / raw) To: Heikki Krogerus, Benson Leung, Jameson Thies Cc: Greg Kroah-Hartman, linux-usb, linux-kernel, Andrei Kuchynski Update the probe function to utilize the new typec_cable_altmode_unsupported() helper. If the cable doesn't support DisplayPort altmode, don't initialize altmode_ops and prevent altmode from being activated. A captive cable shouldn't be checked; it may not provide discoverable capability information, but it is inherently designed to support the device's requirements. Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org> Reviewed-by: Benson Leung <bleung@chromium.org> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> --- drivers/usb/typec/altmodes/displayport.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index 263a89c5f3243..5ee33a69b9cf7 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -790,7 +790,6 @@ int dp_altmode_probe(struct typec_altmode *alt) dp->alt = alt; alt->desc = "DisplayPort"; - typec_altmode_set_ops(alt, &dp_altmode_ops); if (plug) { plug->desc = "Displayport"; @@ -811,6 +810,10 @@ int dp_altmode_probe(struct typec_altmode *alt) if (plug) typec_altmode_set_drvdata(plug, dp); + if ((alt->vdo & DP_CAP_RECEPTACLE) && typec_cable_altmode_unsupported(alt)) + return 0; + + typec_altmode_set_ops(alt, &dp_altmode_ops); if (!alt->mode_selection) { dp->state = plug ? DP_STATE_ENTER_PRIME : DP_STATE_ENTER; schedule_work(&dp->work); -- 2.55.0.rc0.738.g0c8ab3ebcc-goog ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-06-23 8:30 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-22 9:39 [PATCH v2 0/3] Restrict alternate modes based on cable capabilities Andrei Kuchynski 2026-06-22 9:39 ` [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support Andrei Kuchynski 2026-06-22 10:18 ` Heikki Krogerus 2026-06-22 12:03 ` Andrei Kuchynski 2026-06-23 8:30 ` Heikki Krogerus 2026-06-22 9:39 ` [PATCH v2 2/3] usb: typec: thunderbolt: Check " Andrei Kuchynski 2026-06-22 9:39 ` [PATCH v2 3/3] usb: typec: displayport: " Andrei Kuchynski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox