]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: typec: ucsi: Add duplicate detection to nvidia registration path
authorChia-Lin Kao (AceLan) <acelan.kao@canonical.com>
Mon, 13 Jul 2026 08:43:22 +0000 (16:43 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Jul 2026 15:14:27 +0000 (17:14 +0200)
Extend the duplicate altmode detection to ucsi_register_altmodes_nvidia()
which is used when a driver provides the update_altmodes() callback.

This ensures all drivers benefit from duplicate detection, whether they
use the standard registration path or the nvidia path with update_altmodes
callback.

Without this fix, drivers using the nvidia path (like yoga_c630) would
still encounter duplicate altmode registration errors from buggy firmware.

Fixes: a79f16efcd00 ("usb: typec: ucsi: Add support for the partner USB Modes")
Cc: stable <stable@kernel.org>
Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
Link: https://patch.msgid.link/20260713084323.287516-2-acelan.kao@canonical.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/typec/ucsi/ucsi.c

index 0db43521af3fd7e4952812ed2448527f3560e8fa..1ae4224d2dfc3003de529369d9e63649193aed2c 100644 (file)
@@ -706,19 +706,25 @@ ucsi_register_altmodes_nvidia(struct ucsi_connector *con, u8 recipient)
 
        /* now register altmodes */
        for (i = 0; i < max_altmodes; i++) {
-               memset(&desc, 0, sizeof(desc));
-               if (multi_dp) {
-                       desc.svid = updated[i].svid;
-                       desc.vdo = updated[i].mid;
-               } else {
-                       desc.svid = orig[i].svid;
-                       desc.vdo = orig[i].mid;
-               }
-               desc.roles = TYPEC_PORT_DRD;
+               struct ucsi_altmode *altmode_array = multi_dp ? updated : orig;
 
-               if (!desc.svid)
+               if (!altmode_array[i].svid)
                        return 0;
 
+               /*
+                * Check for duplicates in current array and already
+                * registered altmodes. Skip if duplicate found.
+                */
+               if (ucsi_altmode_is_duplicate(con, recipient, altmode_array, i,
+                                             altmode_array[i].svid,
+                                             altmode_array[i].mid, i))
+                       continue;
+
+               memset(&desc, 0, sizeof(desc));
+               desc.svid = altmode_array[i].svid;
+               desc.vdo = altmode_array[i].mid;
+               desc.roles = TYPEC_PORT_DRD;
+
                ret = ucsi_register_altmode(con, &desc, recipient);
                if (ret)
                        return ret;