From: Andrei Kuchynski Date: Mon, 19 Jan 2026 13:18:24 +0000 (+0000) Subject: usb: typec: ucsi: Enforce mode selection for cros_ec_ucsi X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ffbe78fdbbbdf774a92b47ac138bc1a0a7482096;p=thirdparty%2Flinux.git usb: typec: ucsi: Enforce mode selection for cros_ec_ucsi The mode selection sequence is initiated by the driver after all partner alternate modes have been successfully registered. When a partner is disconnected, the driver also stops the mode selection process and releases resources via `typec_mode_selection_delete`. Signed-off-by: Andrei Kuchynski Reviewed-by: Heikki Krogerus Link: https://patch.msgid.link/20260119131824.2529334-8-akuchynski@chromium.org Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/usb/typec/ucsi/cros_ec_ucsi.c b/drivers/usb/typec/ucsi/cros_ec_ucsi.c index eed2a7d0ebc6..6bca2dce211c 100644 --- a/drivers/usb/typec/ucsi/cros_ec_ucsi.c +++ b/drivers/usb/typec/ucsi/cros_ec_ucsi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "ucsi.h" @@ -33,6 +34,11 @@ /* Number of times to attempt recovery from a write timeout before giving up. */ #define WRITE_TMO_CTR_MAX 5 +/* Delay between mode entry/exit attempts, ms */ +static const unsigned int mode_selection_delay = 1000; +/* Timeout for a mode entry attempt, ms */ +static const unsigned int mode_selection_timeout = 4000; + struct cros_ucsi_data { struct device *dev; struct ucsi *ucsi; @@ -134,6 +140,20 @@ static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci, return ret; } +static void cros_ucsi_add_partner_altmodes(struct ucsi_connector *con) +{ + if (!con->typec_cap.no_mode_control) + typec_mode_selection_start(con->partner, + mode_selection_delay, + mode_selection_timeout); +} + +static void cros_ucsi_remove_partner_altmodes(struct ucsi_connector *con) +{ + if (!con->typec_cap.no_mode_control) + typec_mode_selection_delete(con->partner); +} + static const struct ucsi_operations cros_ucsi_ops = { .read_version = cros_ucsi_read_version, .read_cci = cros_ucsi_read_cci, @@ -141,6 +161,8 @@ static const struct ucsi_operations cros_ucsi_ops = { .read_message_in = cros_ucsi_read_message_in, .async_control = cros_ucsi_async_control, .sync_control = cros_ucsi_sync_control, + .add_partner_altmodes = cros_ucsi_add_partner_altmodes, + .remove_partner_altmodes = cros_ucsi_remove_partner_altmodes, }; static void cros_ucsi_work(struct work_struct *work)