Skip to content

Commit 3b8ae98

Browse files
Andrei Kuchynskigregkh
authored andcommitted
usb: typec: thunderbolt: Set enter_vdo during initialization
In the current implementation, if a cable's alternate mode enter operation is not supported, the tbt->plug[TYPEC_PLUG_SOP_P] pointer is cleared by the time tbt_enter_mode() is called. This prevents the driver from identifying the cable's VDO. As a result, the Thunderbolt connection falls back to the default TBT_CABLE_USB3_PASSIVE speed, even if the cable supports higher speeds. To ensure the correct VDO value is used during mode entry, calculate and store the enter_vdo earlier during the initialization phase in tbt_ready(). Cc: stable <stable@kernel.org> Fixes: 100e257 ("usb: typec: Add driver for Thunderbolt 3 Alternate Mode") Tested-by: Madhu M <madhu.m@intel.corp-partner.google.com> Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Reviewed-by: Benson Leung <bleung@chromium.org> Link: https://patch.msgid.link/20260324103012.1417616-1-akuchynski@chromium.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent b65d4ca commit 3b8ae98

1 file changed

Lines changed: 22 additions & 22 deletions

File tree

drivers/usb/typec/altmodes/thunderbolt.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,7 @@ static bool tbt_ready(struct typec_altmode *alt);
3939

4040
static int tbt_enter_mode(struct tbt_altmode *tbt)
4141
{
42-
struct typec_altmode *plug = tbt->plug[TYPEC_PLUG_SOP_P];
43-
u32 vdo;
44-
45-
vdo = tbt->alt->vdo & (TBT_VENDOR_SPECIFIC_B0 | TBT_VENDOR_SPECIFIC_B1);
46-
vdo |= tbt->alt->vdo & TBT_INTEL_SPECIFIC_B0;
47-
vdo |= TBT_MODE;
48-
49-
if (plug) {
50-
if (typec_cable_is_active(tbt->cable))
51-
vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
52-
53-
vdo |= TBT_ENTER_MODE_CABLE_SPEED(TBT_CABLE_SPEED(plug->vdo));
54-
vdo |= plug->vdo & TBT_CABLE_ROUNDED;
55-
vdo |= plug->vdo & TBT_CABLE_OPTICAL;
56-
vdo |= plug->vdo & TBT_CABLE_RETIMER;
57-
vdo |= plug->vdo & TBT_CABLE_LINK_TRAINING;
58-
} else {
59-
vdo |= TBT_ENTER_MODE_CABLE_SPEED(TBT_CABLE_USB3_PASSIVE);
60-
}
61-
62-
tbt->enter_vdo = vdo;
63-
return typec_altmode_enter(tbt->alt, &vdo);
42+
return typec_altmode_enter(tbt->alt, &tbt->enter_vdo);
6443
}
6544

6645
static void tbt_altmode_work(struct work_struct *work)
@@ -337,6 +316,7 @@ static bool tbt_ready(struct typec_altmode *alt)
337316
{
338317
struct tbt_altmode *tbt = typec_altmode_get_drvdata(alt);
339318
struct typec_altmode *plug;
319+
u32 vdo;
340320

341321
if (tbt->cable)
342322
return true;
@@ -364,6 +344,26 @@ static bool tbt_ready(struct typec_altmode *alt)
364344
tbt->plug[i] = plug;
365345
}
366346

347+
vdo = tbt->alt->vdo & (TBT_VENDOR_SPECIFIC_B0 | TBT_VENDOR_SPECIFIC_B1);
348+
vdo |= tbt->alt->vdo & TBT_INTEL_SPECIFIC_B0;
349+
vdo |= TBT_MODE;
350+
plug = tbt->plug[TYPEC_PLUG_SOP_P];
351+
352+
if (plug) {
353+
if (typec_cable_is_active(tbt->cable))
354+
vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
355+
356+
vdo |= TBT_ENTER_MODE_CABLE_SPEED(TBT_CABLE_SPEED(plug->vdo));
357+
vdo |= plug->vdo & TBT_CABLE_ROUNDED;
358+
vdo |= plug->vdo & TBT_CABLE_OPTICAL;
359+
vdo |= plug->vdo & TBT_CABLE_RETIMER;
360+
vdo |= plug->vdo & TBT_CABLE_LINK_TRAINING;
361+
} else {
362+
vdo |= TBT_ENTER_MODE_CABLE_SPEED(TBT_CABLE_USB3_PASSIVE);
363+
}
364+
365+
tbt->enter_vdo = vdo;
366+
367367
return true;
368368
}
369369

0 commit comments

Comments
 (0)