From nobody Mon Dec 1 22:03:17 2025 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3EA5A30FC25 for ; Mon, 1 Dec 2025 12:26:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764591993; cv=none; b=tumLAovSyXRwe0TFxO1B78uXRkvpMFNMFeCmo9cJmOzdUyhaKyHgiaNEC9ncqTEvQvdN50VMctAEPpeY6zjQ74cXX9CYWsaW6Wh37mewxshQEXlWYOaJ6p5s8ePVttPKapEKAx4quEsPkqQjipeykE+I79GZoyaalzXiM4mFyvs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764591993; c=relaxed/simple; bh=8/vLyDy3MTFQaWy0TuwBeVxho4lSfebWQQDxH1LU0Dc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rENf6HqqJ0g1YsyW8cIdG9UvYPjWQXISibs9NKK8cT/Jit+mzN8xd2JStrHE7M8bBlTvZIo1iTRlb0s3wqYFBGncDZyT4B53+/jIlMpfg1APhJY/ERkr2OXpW3F/xhRM4TEBtVYDuvykv+DSZ9TE8jcvSDsmpfqsh/GF3sDND7s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=E2VGiZUm; arc=none smtp.client-ip=209.85.218.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="E2VGiZUm" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-b73a9592fb8so1071486566b.1 for ; Mon, 01 Dec 2025 04:26:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1764591989; x=1765196789; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=g1naprGdujl0hDct49jHvoowZM6Cf+zk8w9Ns/4eimc=; b=E2VGiZUmmrIaGREcEYJoI4EQo1pgD7y0z6T9LzM8PgL5L/TaSowXlRthWVRWirshUF RguA/ApMl1lwaGY8J8mkUYf6ryWnmDHe0E89TRm13qb1zIQ/KGBaeolVTwg8+t4VB8yi tR4p4vvK7EUwlbvbKluDAC1QOiZX5pP3mgw0E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764591989; x=1765196789; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=g1naprGdujl0hDct49jHvoowZM6Cf+zk8w9Ns/4eimc=; b=eYAOMt9WwQUn+VY/WvJ4tUckE3I5d3PicFMeBbHP2kA8vAiLsGAAQiT4LfekQNDvmS 5mRcdiumksOXnuCAant4a6KMCOGu2xv0EtnObILsdtRJo3ozvUCGLExL/25Pv59H0zsa EESdyjZQVc82q63ZNNKTC09GLySbu0y2HPHtCIAS32z7t/er7zk0tr80SaMjZxRaASYO UVjiW+7Y+ZOEWFqek94n4ZgJbUarhh9cNwuaGdfrkuYv6XKK9dgflAm8wTdrMtvOMxBO IbsrhJwhOqsMWMaRCuVVezF/FsSsTyQWr6IV7j57NjZCCoq7PMy6qwqTM5N40HyW8Aip F3+A== X-Forwarded-Encrypted: i=1; AJvYcCUd6DcBVdHTchHx6uVxQTMK853FsswvA0+N9W0x4IlfWxkBY91JZKmo32594ad+GeiYMuOOs7Xc981llLQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwFBBCr2KwTbQ4s2fGSSgJS80ab+EU7j0aaETU3tuNyH7Y4kI18 SMOCMt3kpPQDNt5K5kLXcCQVzow2Q64tkYLjNc4TR9UgF+cqTvnxbcfkUykyfh7HSg== X-Gm-Gg: ASbGncur748XkLTok7N1wS99IEhed5NYqQxz08GR20lDgvZZmMwG5ziEFd2WVXqVfNO nmtOinLfkl7/DuOcn8mwJJ3ILc0hAbVfW5t/Z04eBeSubobURhhIPeXNmVoHPNVhta7xAH/dNIs AgrkI7L5iyzjsztmC9CBmdZfM0OI+MkERCvPg4FQrUR/+v4e3OMm7b0qLnLUunQ+YCrdyvQA3as 6RCshzpJL8zsJQGyPMly0yDtIcNbMRO8KkQ6Qk5oADTZaT1v2LWb4VN4zBtXG5xfU4eASWLzkVG ZCpF5LYeLj1VXYZt1QcnZshgdqRcT8XHduREQ1LfS8YnlCPMQCdCdjY63Xu3pbZQqwUdCm5tytY 6j3ge74XS/JCw7QRFoMfUgrymz5o+I8Aht/xS0HioQo7/PrftxdDVMCNPQ/vjFzPXfDfqn29rSz IO/n8EI1Hvr+85wKm2bCRiS53GpxWrJjfPYC7aj3wAwqxdFS5QT2Pjv5/r8iGEYerpYuCZnOant b20RJ8AGqM= X-Google-Smtp-Source: AGHT+IFu9VlvB+GE4wPCZvLjBJQVkYcCGQiYYmtpwkbYyZkwNjLgf5X/ol5wQZA4UhW+seYvD1Sedw== X-Received: by 2002:a17:907:1ca4:b0:b6d:5dbb:a1e1 with SMTP id a640c23a62f3a-b766ed8362dmr4714235166b.5.1764591989425; Mon, 01 Dec 2025 04:26:29 -0800 (PST) Received: from akuchynski.c.googlers.com.com (218.127.147.34.bc.googleusercontent.com. [34.147.127.218]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b76f519e331sm1229049266b.24.2025.12.01.04.26.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Dec 2025 04:26:29 -0800 (PST) From: Andrei Kuchynski To: Heikki Krogerus , Abhishek Pandit-Subedi , Benson Leung , Jameson Thies , Tzung-Bi Shih , linux-usb@vger.kernel.org, chrome-platform@lists.linux.dev Cc: Guenter Roeck , Greg Kroah-Hartman , Dmitry Baryshkov , "Christian A. Ehrhardt" , Abel Vesa , Pooja Katiyar , Pavan Holla , Madhu M , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH RFC 8/8] platform/chrome: cros_ec_typec: Enforce priority-based mode selection Date: Mon, 1 Dec 2025 12:26:04 +0000 Message-ID: <20251201122604.1268071-9-akuchynski@chromium.org> X-Mailer: git-send-email 2.52.0.158.g65b55ccf14-goog In-Reply-To: <20251201122604.1268071-1-akuchynski@chromium.org> References: <20251201122604.1268071-1-akuchynski@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The driver sets mode_selection bit for each Alternate mode, thereby preventing individual altmode drivers from activating their respective modes. Once the registration of all Alternate Modes is complete, the driver invokes typec_mode_selection_start to initiate the mode selection process based on mode priorities. The driver communicates the current Type-C mode to the mode selection process via typec_altmode_state_update. Signed-off-by: Andrei Kuchynski --- drivers/platform/chrome/cros_ec_typec.c | 47 +++++++++++++++----- drivers/platform/chrome/cros_typec_altmode.c | 8 +++- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chr= ome/cros_ec_typec.c index c0806c562bb9..cd827b1822e2 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -27,6 +27,11 @@ BIT(DP_PIN_ASSIGN_D) | \ BIT(DP_PIN_ASSIGN_E))) =20 +/* Delay between mode entry/exit attempts, ms */ +static const unsigned int mode_selection_delay =3D 1000; +/* Timeout for a mode entry attempt, ms */ +static const unsigned int mode_selection_timeout =3D 4000; + static void cros_typec_role_switch_quirk(struct fwnode_handle *fwnode) { #ifdef CONFIG_ACPI @@ -325,6 +330,7 @@ static void cros_typec_remove_partner(struct cros_typec= _data *typec, if (!port->partner) return; =20 + typec_mode_selection_delete(port->partner); cros_typec_unregister_altmodes(typec, port_num, true); =20 typec_partner_set_usb_power_delivery(port->partner, NULL); @@ -400,17 +406,6 @@ static int cros_typec_register_port_altmodes(struct cr= os_typec_data *typec, struct typec_altmode_desc desc; struct typec_altmode *amode; =20 - /* All PD capable CrOS devices are assumed to support DP altmode. */ - memset(&desc, 0, sizeof(desc)); - desc.svid =3D USB_TYPEC_DP_SID; - desc.mode =3D USB_TYPEC_DP_MODE; - desc.vdo =3D DP_PORT_VDO; - amode =3D cros_typec_register_displayport(port, &desc, - typec->ap_driven_altmode); - if (IS_ERR(amode)) - return PTR_ERR(amode); - port->port_altmode[CROS_EC_ALTMODE_DP] =3D amode; - /* * Register TBT compatibility alt mode. The EC will not enter the mode * if it doesn't support it and it will not enter automatically by @@ -428,6 +423,17 @@ static int cros_typec_register_port_altmodes(struct cr= os_typec_data *typec, port->port_altmode[CROS_EC_ALTMODE_TBT] =3D amode; } =20 + /* All PD capable CrOS devices are assumed to support DP altmode. */ + memset(&desc, 0, sizeof(desc)); + desc.svid =3D USB_TYPEC_DP_SID; + desc.mode =3D USB_TYPEC_DP_MODE; + desc.vdo =3D DP_PORT_VDO; + amode =3D cros_typec_register_displayport(port, &desc, + typec->ap_driven_altmode); + if (IS_ERR(amode)) + return PTR_ERR(amode); + port->port_altmode[CROS_EC_ALTMODE_DP] =3D amode; + port->state.alt =3D NULL; port->state.mode =3D TYPEC_STATE_USB; port->state.data =3D NULL; @@ -742,6 +748,7 @@ static int cros_typec_configure_mux(struct cros_typec_d= ata *typec, int port_num, enum typec_orientation orientation; struct cros_typec_altmode_node *node; int ret; + u16 active_svid =3D 0; =20 ret =3D cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_MUX_INFO, &req, sizeof(req), &resp, sizeof(resp)); @@ -780,10 +787,13 @@ static int cros_typec_configure_mux(struct cros_typec= _data *typec, int port_num, =20 if (port->mux_flags & USB_PD_MUX_USB4_ENABLED) { ret =3D cros_typec_enable_usb4(typec, port_num, pd_ctrl); + active_svid =3D USB_TYPEC_USB4_SID; } else if (port->mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) { ret =3D cros_typec_enable_tbt(typec, port_num, pd_ctrl); + active_svid =3D USB_TYPEC_TBT_SID; } else if (port->mux_flags & USB_PD_MUX_DP_ENABLED) { ret =3D cros_typec_enable_dp(typec, port_num, pd_ctrl); + active_svid =3D USB_TYPEC_DP_SID; } else if (port->mux_flags & USB_PD_MUX_SAFE_MODE) { ret =3D cros_typec_usb_safe_state(port); } else if (port->mux_flags & USB_PD_MUX_USB_ENABLED) { @@ -799,6 +809,9 @@ static int cros_typec_configure_mux(struct cros_typec_d= ata *typec, int port_num, port->mux_flags); } =20 + if (port->partner) + typec_altmode_state_update(port->partner, active_svid, ret); + /* Iterate all partner alt-modes and set the active alternate mode. */ list_for_each_entry(node, &port->partner_mode_list, list) { typec_altmode_update_active( @@ -899,6 +912,7 @@ static int cros_typec_register_altmodes(struct cros_typ= ec_data *typec, int port_ memset(&desc, 0, sizeof(desc)); desc.svid =3D sop_disc->svids[i].svid; desc.mode =3D j + 1; + desc.mode_selection =3D typec->ap_driven_altmode; desc.vdo =3D sop_disc->svids[i].mode_vdo[j]; =20 if (is_partner) @@ -940,6 +954,17 @@ static int cros_typec_register_altmodes(struct cros_ty= pec_data *typec, int port_ goto err_cleanup; } =20 + /* Once all partner alt-modes are added, we should also trigger + * mode selection. + */ + if (is_partner && typec->ap_driven_altmode) { + ret =3D typec_mode_selection_start(port->partner, + mode_selection_delay, mode_selection_timeout); + if (ret < 0) + dev_err(typec->dev, + "Unable to run mode selection on port%d partner\n", port_num); + } + return 0; =20 err_cleanup: diff --git a/drivers/platform/chrome/cros_typec_altmode.c b/drivers/platfor= m/chrome/cros_typec_altmode.c index 557340b53af0..ee4f2a9dd68a 100644 --- a/drivers/platform/chrome/cros_typec_altmode.c +++ b/drivers/platform/chrome/cros_typec_altmode.c @@ -41,12 +41,16 @@ static void cros_typec_altmode_work(struct work_struct = *work) { struct cros_typec_altmode_data *data =3D container_of(work, struct cros_typec_altmode_data, work); + int ret; =20 mutex_lock(&data->lock); =20 - if (typec_altmode_vdm(data->alt, data->header, data->vdo_data, - data->vdo_size)) + ret =3D typec_altmode_vdm(data->alt, data->header, data->vdo_data, + data->vdo_size); + if (ret) { dev_err(&data->alt->dev, "VDM 0x%x failed\n", data->header); + typec_altmode_state_update(data->port->partner, data->sid, ret); + } =20 data->header =3D 0; data->vdo_data =3D NULL; --=20 2.52.0.158.g65b55ccf14-goog