From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) (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 49E0324466C for ; Mon, 4 Aug 2025 09:04:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298248; cv=none; b=nb+bxJLq7YestYf3khGhdhZecumB0YSD6ykepdVZYybJYof69C+qPLWy3DbkGzD0SovfQUjnx7Po3KB3Qfr1EEfeFqr1+Pvjl7DuJ9hg3CZ6fUaNKeiIxBOwnL2BozLvhcbFSCkqJ17SyqKSqCmM3gRTk7UNc+pXyRRSrI+JwLg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298248; c=relaxed/simple; bh=SeYBoLiLdsd4RYBx+xmk62y4glTyVdE4JpC5IMRPlMo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X5OMC6VHJL8QwQwDhlHOKjttOR5gXG6nIvWCHBg4vGFSbTgmePnAo7taKqiHHr+mwlxWmCi4rb6ITcKriKCechXqnzNwJT8bBBeJ/rsFRifmpzn4HD9JSNlPHTldQj8weMMPFp9b7zQ5lCybdknCecmjCOYLurN0k+3r/QOI0FA= 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=luiiZTaN; arc=none smtp.client-ip=209.85.218.50 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="luiiZTaN" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-af949891d3aso236064766b.1 for ; Mon, 04 Aug 2025 02:04:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298245; x=1754903045; 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=QbhdT3BVEtPsr7nMwgyR5zxNdwkZ/IAe0pEt6XO5SM8=; b=luiiZTaNv7Qxi1lKhzxANGHnOQk5b6aiP0HwgCFXaiC7apueLzmcFu9sA039Ws7N26 b0Xa2rxNdJaVPiNg74xVWCO0dkVrAlLOKeKCUUE+WPst7ZZvFJ+6exvUjnCUb3ULWeOJ 13PSA3QkgJBtvJURdLNRZPknWrBlF3jk63+nI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298245; x=1754903045; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QbhdT3BVEtPsr7nMwgyR5zxNdwkZ/IAe0pEt6XO5SM8=; b=EaGxmKLrsBRvGIrda/z3SeObSQwO8DuZgKU7/NpSfwhCJBvdtLhrwEzmBwvuyx3Ax9 eRDGfkXn8UF1WfFnx4sCkucbN0SGMxVrwXI6TMhsygwinpOv6EreCPf9gOJXzOlNn9Sg zrrDQtkl2yhX2uhymvhyMg02ATlSK0vMBc3OU2AUB1yLsd/HciKmsR81Ls66LxORMvMs 2OW5dgU2ziofyPA4XJQE0EIJ+uyPXXNFrXhktVVRl9reMBgMavDMG/ccAZQJmjA0SjqR ULGmmOR7A/vPVyrJPMkFA17MTkv+HrShoUA6kUZU2bqNPeIW16M+ZuVIKN0f22pjaoYr vWzw== X-Forwarded-Encrypted: i=1; AJvYcCWpPO3tmxODCyEeRLmW//bLDTCG/0ralijvFSgGPq1lnRwixfVIhFVZ0v2Lwp7LvIspqkol+MFPKPMT4Tc=@vger.kernel.org X-Gm-Message-State: AOJu0YwMBfFLNFX6XRcQy5Ets5WIxlA1kDe96MtEIsArLDCTpJH4b8pf QaBgBonI2f0ijBlMsVCkSFbbv0iBKU7nOD8f4Uz/udvvTUL8dP0PaXVRJsO7aajBcg== X-Gm-Gg: ASbGncs0R7pLkyEYZMQTku2LvX6zCNCWqUU4OpOXyNHQfX4KLSeQXxIMK7hThwpU97Y WoU/fM5WjcGwYbo4AbHQNt6Vrz0b+2pBue1iEVv8p/MLlBFzb2bcK3u0ST2EONhN0K388YnPHdx VTZhjkN7Jx/CfYWjbnp4gxA5HmkXuiBDDZqex6T5W6McVG7Isr+eASSbwWxpVUpDFqxqOEVQeYW 9reEmcfj+sH5dEkODy0eVdNY6FhHsQaxW9TWuq8UQFsI2QbGpo+WoyjlXiUSXyIzhm2t1r5OovR ZjC9JGp0wZ+4+L/3AFXfisK5RMLAH+FX9yr0VO/7wfTECPN5fc2WLVvsRiZy5RbqSMshLtnUxyi cBSVEGmMNyoIrj01df/vanBlRDdjVp22R6iIUkyVRjFvlfxcIbJh193wzlCRcpZEeHP7DcvINcF yY6kv5n4TudkVLvjNszsS3pHCp+Q== X-Google-Smtp-Source: AGHT+IGevy8HvEbH/6/5kPktQXX98NEixPFRIRgQ3eseS1Hs85sSCgqCJM8sG0Zq21CouJBtYcjtwQ== X-Received: by 2002:a17:907:6d1f:b0:af9:e9a:3ce9 with SMTP id a640c23a62f3a-af940031934mr1082193166b.10.1754298244562; Mon, 04 Aug 2025 02:04:04 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:03 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 01/10] usb: typec: Add alt_mode_override field to port property Date: Mon, 4 Aug 2025 09:03:30 +0000 Message-ID: <20250804090340.3062182-2-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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" This new field in the port properties dictates whether the Platform Policy Manager (PPM) allows the OS Policy Manager (OPM) to change the currently active, negotiated alternate mode. Signed-off-by: Andrei Kuchynski --- drivers/usb/typec/class.c | 14 +++++++++++--- drivers/usb/typec/class.h | 2 ++ include/linux/usb/typec.h | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 67a533e35150..a72325ff099a 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -459,9 +459,16 @@ static umode_t typec_altmode_attr_is_visible(struct ko= bject *kobj, struct typec_altmode *adev =3D to_typec_altmode(kobj_to_dev(kobj)); =20 if (attr =3D=3D &dev_attr_active.attr) - if (!is_typec_port(adev->dev.parent) && - (!adev->ops || !adev->ops->activate)) - return 0444; + if (!is_typec_port(adev->dev.parent)) { + struct typec_partner *partner =3D + to_typec_partner(adev->dev.parent); + struct typec_port *port =3D + to_typec_port(partner->dev.parent); + + if (!port->alt_mode_override || !adev->ops || + !adev->ops->activate) + return 0444; + } =20 return attr->mode; } @@ -2681,6 +2688,7 @@ struct typec_port *typec_register_port(struct device = *parent, } =20 port->pd =3D cap->pd; + port->alt_mode_override =3D cap->alt_mode_override; =20 ret =3D device_add(&port->dev); if (ret) { diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index db2fe96c48ff..f05d9201c233 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -80,6 +80,8 @@ struct typec_port { */ struct device *usb2_dev; struct device *usb3_dev; + + bool alt_mode_override; }; =20 #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev) diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 252af3f77039..6e09e68788dd 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -304,6 +304,7 @@ struct typec_capability { enum typec_accessory accessory[TYPEC_MAX_ACCESSORY]; unsigned int orientation_aware:1; u8 usb_capability; + bool alt_mode_override; =20 struct fwnode_handle *fwnode; void *driver_data; --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) (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 CB33A242D9E for ; Mon, 4 Aug 2025 09:04:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298266; cv=none; b=Y0t49uT1gFFVuOuhp3M2ZUy2R6wfWFfVO5xYi0rGCVqhFGrwL+M5b0tejEzTsj/IibHNxN3/T9VAV4P9n6aSAvQr5JYFu05iOPdctpOD7dnq1o8h3piMDy1tm2qphwifRiB1xe/bPwJH7EqOhLSvGdCI+qa65gkDRe21+uplW5o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298266; c=relaxed/simple; bh=ud242vZvLJrH6xopdOSJSplgPyMO56QkORuiEVdjqaM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k3lLIeNoCaWBO5y0SRb6VQ6lI3AHkzkyqAWwBosTyDj7sfGwupQwByk2mcx0HGx+SVZhXgolErBC8sfQZonMo2pfbJorsme/Qq6X7y1l/FCiC3kha0EU1edQSUwCxY3G9xrCTfnySZ3PgrfhEg5WrrCatqkUJvfqv1onRCXrgMU= 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=ImkirbJN; arc=none smtp.client-ip=209.85.208.50 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="ImkirbJN" Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-6156a162537so6219995a12.2 for ; Mon, 04 Aug 2025 02:04:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298263; x=1754903063; 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=tHnJVEZKYStNja74J0DOKbp6uiLWBK5/zflpDmAO16o=; b=ImkirbJN92IMT6tsK54LdlfJu4E6tts24A0lLR1npks2fTb6EQZjPy21ZZC1mg2igv qeUPlw8b3Q4X+5Z8+l9DkDzOxb91UkBuMNCx+2SYTEPLD1nD20udcDSoVnZgVd+Hkork dgwmEx9DzcMsZqByOwReefJD/K01Dey/FkhMs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298263; x=1754903063; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tHnJVEZKYStNja74J0DOKbp6uiLWBK5/zflpDmAO16o=; b=OewM/pQztj12SlZVzTBJm1imK98CT2Rszh8oUafu1xwMRYM0XrLidW1JCsKMLtdjFI 6HRVOYY7vpLyPToBrj+3qzOhHPVtrYvwXwqd0usWz7ZX8N/6WkxhcQFhwTuG8QUIi5U9 Cajn2n4JDZUKxeOdAOWeXGvLQBy2zG5YN0DA7epVdWsT/Ztqj1a3h8eJKjHO93llGBOX Tk+4KMM1JTv7g+6B4MpS9qd0MEe0S+3Ttu5I840DpEytUhTAfWj9fRZqnS8+WyyAU+IA LLgZBy2svqRHnoVTpmxA9rqcZvHb9wyKL5JfxyJK0VdpE5XORtWyqtpBI2t6wALjWX+6 gWBQ== X-Forwarded-Encrypted: i=1; AJvYcCXvl6n25I4jJZ6jjnFMSCDWARsjjoAHze3qUI1aScVrie7Ka2hyISOkZT5tnLL0V/QuNFUIErrOOMf9lFM=@vger.kernel.org X-Gm-Message-State: AOJu0YxZ61zbVIn3bkRLl/k2PJYxBWxtgUG0xPkSx7Cbel0aT6aw2cgp k51WJ6sP5+ZnAPPYOCIo1EWmmxht51gxyaENt3NxSkXCJ34z68bi9gt0AZ7WYhanMw== X-Gm-Gg: ASbGncuGnDDLeQh4/rQEl0L8CGLZ98CoC7x2+ggjE9CP31aYRih9KnKbPE0o18whR3D hXV/f68F7P+0oJBIgDc3ODYen61IjGwh/jGfCWN/HB5IQSMj1yayLK0HHdN4z+uJf/iFnRHZxJy lo0pro5V+0JCRnmST85qZ9pqVZO649QSQTec1A7KB00amptA+2Y6Po9vsfM3bK/BiR8EJN7FOKp hnSD8kD0rlxInKzj6pmYDOIBt7t3zz3QLqqvyPDqNLox0LhqWpBMOvbCqZ1kAT47Yej7dEvHm+q CTK2fOeaF4clshP+JY+1exxf8q70cHTNanrNuzVYcbZMS0gx0HTKl+ZXLNaVFs7O17IBH2L1RiW t7QoRR7VTJnePsoFW/CkPPoqdC0SPQScwBgezUrnnn5NOxfdtLhRANzbPr7AcE/UL0lgy/I4st7 LVSDgXVnw/r3Kf21K/6x8sI5cNIg== X-Google-Smtp-Source: AGHT+IGlP1mTwXR2PA9n8SopXtLR0QRbnOxjHuzCPP04R6m/RhGzUKKa90WwYf+waVhclx/pDtB5+A== X-Received: by 2002:a05:6402:90c:b0:615:6fae:d766 with SMTP id 4fb4d7f45d1cf-615e73889a3mr7449193a12.26.1754298263208; Mon, 04 Aug 2025 02:04:23 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:22 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 02/10] platform/chrome: cros_ec_typec: Set alt_mode_override flag Date: Mon, 4 Aug 2025 09:03:31 +0000 Message-ID: <20250804090340.3062182-3-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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" This flag specifies that the Embedded Controller (EC) must receive explicit approval from the Application Processor (AP) before initiating Type-C alternate modes or USB4 mode. Signed-off-by: Andrei Kuchynski --- drivers/platform/chrome/cros_ec_typec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chr= ome/cros_ec_typec.c index b712bcff6fb2..99f549263c37 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -491,6 +491,7 @@ static int cros_typec_init_ports(struct cros_typec_data= *typec) =20 cap->driver_data =3D cros_port; cap->ops =3D &cros_typec_usb_mode_ops; + cap->alt_mode_override =3D typec->ap_driven_altmode; =20 cros_port->port =3D typec_register_port(dev, cap); if (IS_ERR(cros_port->port)) { --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.48]) (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 9E723246799 for ; Mon, 4 Aug 2025 09:04:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298270; cv=none; b=mHIvIHJLKz+QcbYzogtdISa30oRxtRaAyvYGOVgZq4w9gkbJgGlZuLv2UG4qWOjM8lSKeJN8aeZjFVGYFZJNZPS8Istd16UUpEbSOtQ1f8N7/nruwa7hqeURseMnIyPiMwZLoYIdDV0eyFdfRrFjqJ6ZpgH5UXKLPxMJVvz/OEg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298270; c=relaxed/simple; bh=6Bhn8TVLiVPA/DDpJF49VzDOxmDs4HWaQoUsOlq8plg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HK3/Efk98yV20vH1S1UoWI2OkflEY6kOvxIL/E//rf4vYTk45tT3Epr40tZu8nG1WjEWt5ztT4QBhdHzB4Oa1Ju/2ZlN0PdC/6vbsQPjj/SCCnM5BaaEgwWdNx5TzRx6fqjrDtTnX40BrjnMD/hGYOH3KkcNgR4iVoa2APsLqEQ= 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=jJyl4LcO; arc=none smtp.client-ip=209.85.208.48 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="jJyl4LcO" Received: by mail-ed1-f48.google.com with SMTP id 4fb4d7f45d1cf-61568fbed16so4565992a12.3 for ; Mon, 04 Aug 2025 02:04:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298266; x=1754903066; 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=q3zkd9Jg/1IWWLetRvam/cO4b58x4mGvV5kNliFnOgc=; b=jJyl4LcOJBO5otJknHkRY/bMMfr5oiaGH7EBn8iOgq2AWsTwlWvVe800vlvTmO2fw0 cf3+XBkXt3DJNV5KlgJupLvMIn6fQrz8f1VEuVCTtsOfD6HMDv5Z+V9kghIMi6kub8yy ozLsiXXSAOB2SDDo/oOs8EZaZQqQ8bSF5bc60= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298266; x=1754903066; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=q3zkd9Jg/1IWWLetRvam/cO4b58x4mGvV5kNliFnOgc=; b=uMwOtis3iJVF/9IZ9T+bd9yZ+3GzNLp4IcRa/0RSXcA7fHgFQ4vpZSqF01XDIswnRV 9G4GpCwiLjmP4U196i7pAoppwLorVBiACFj+txAL77ar5ieZJbUFV0ToVQq0Y32hr9g3 YStUxVeh81ksMzknBSsoS3JJRCPr4cBuvShZZYU6HzrvKemdxdbFsl3M/YjTl7S4yHG9 LT9Eh5RKiyL9iNHQwkhYBtIZSJSPAHrW6NnBMV2uVp/DLVDVBx9SyznEMp+bkAlasNW3 COdCRwtD8EVUoRPdDMiK+Xz7auikXBDvYGjeCey8p9l5xTAeV8B0OzrVX/fmG/rNnBEV eAmQ== X-Forwarded-Encrypted: i=1; AJvYcCUHr6mZKX9lm8SreLd6EIsyiPk5BGvHYet9WccXOww8xe/HEyuuvUVQw8n9tS4I5zDyDTbuGw5Hhwb6i44=@vger.kernel.org X-Gm-Message-State: AOJu0Yyvworu2sEwCvqTzGfveTL3BP4MnHTQ4EctFQb1X1DuuOk7fbUc Z6Nb7UqnHtTW1J6jyZC1rAuCsxyZTgt132+fOM4ZvS6LUH4F4ecmMaIfZX1GQCkqrw== X-Gm-Gg: ASbGncsNGDaROMPcVP1zI5z8+gx0cwOfirONkEhht5ihNS/rMRhqmMOlnhlN4ZzX6Xo jbAsXEbM2tLeSAIgR+7mSC1IA/0IYPir702RyfxPpMZmw6Omo5NROm45M9KJK23JLWhQTck1COH GxkAnH8xsDf4euIBqLwJeuTgWh5MWgTC5FdnrsdjUvrCawmpmXx8sX5SJySeh98Ep+L5ebDgw12 IdMtgKJOOGxzw+pWpxa/9GI3Ea6AUQ7QLldcDbYrhdL33yg9UtZnPUJ93LwfDaH6B1aYzB/oi9V FJxB/FmIKOUhqnFcr39k+1Q/Mq2+F+aR+/eQhZOP9G4eDbRQ+KmUMmRJSTCQuwrWUKpydc2HTSP a8r0/C7nYGcZGX8KafDsXzI5K/K7ryg0Crmg85Hzjvh+xwkRYFSz7upLDsRyZDQx9XSB4Ru/18I nT4iu6j7b4Glt7+FQ= X-Google-Smtp-Source: AGHT+IGW/LCLdhCJc2+ufotVYylvigS+HVY0E50Z6NorO+AWbE3p7ae6GP/d5eD1odizSiqENv3SHw== X-Received: by 2002:a05:6402:40c5:b0:615:a60a:38a7 with SMTP id 4fb4d7f45d1cf-615e6eb549dmr7470597a12.7.1754298265812; Mon, 04 Aug 2025 02:04:25 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:25 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 03/10] usb: typec: ucsi: Set alt_mode_override flag Date: Mon, 4 Aug 2025 09:03:32 +0000 Message-ID: <20250804090340.3062182-4-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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" This flag indicates that the PPM allows the OPM to change the currently negotiated alternate mode using the SET_NEW_CAM command. Signed-off-by: Andrei Kuchynski --- drivers/usb/typec/ucsi/ucsi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 5739ea2abdd1..5ba8b1bc874b 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -1616,6 +1616,8 @@ static int ucsi_register_port(struct ucsi *ucsi, stru= ct ucsi_connector *con) =20 cap->driver_data =3D con; cap->ops =3D &ucsi_ops; + cap->alt_mode_override =3D + !!(con->ucsi->cap.features & UCSI_CAP_ALT_MODE_OVERRIDE); =20 if (ucsi->ops->update_connector) ucsi->ops->update_connector(con); --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ed1-f41.google.com (mail-ed1-f41.google.com [209.85.208.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 9AF19247287 for ; Mon, 4 Aug 2025 09:04:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298273; cv=none; b=HfRfLyKSvWOyrgRgbn+f1gEl7wH1w0rHhxI67MTysxBvIOj0Ud+ZjqGlYvs8olg32rSoA55K8OG2ZeqMiAe+4jVDqyJLjMAG24pR7T+2Pt30HSgx1JuofJVJ25pUixhC35txdOXetIQVqyPeSO1v9B0zQKd/W1QY5170vCuCt8A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298273; c=relaxed/simple; bh=xkMlzpbG01T+w0WOqF7niNZLHXyYGCXdCyisCwJ+khw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qhGir7laRIu4wHF3VGLpQ+sMt3SAyCBPQ1pecoph0QtuKL4Fh2BzSN6+lX8THwZVdg6AjZLVkD3x4OlCQ/HIICe1u0q3dmA8aWSPeT627Y7tfNE9/EQFq00EeyWPAaLP91FtH+j92Z+CXJv7/6j7QVYk+hePA4PP7xoVscRPNGc= 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=OwbWL/As; arc=none smtp.client-ip=209.85.208.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="OwbWL/As" Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-61568fbed16so4566066a12.3 for ; Mon, 04 Aug 2025 02:04:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298269; x=1754903069; 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=C/YntZK0scRDzUtpLUdif5ObE8XPBblzRqTujLBoEls=; b=OwbWL/AskELe2+X9kZxcPjuQoJjgvTpo7ghwbwmHEUr71F60jxvyT08aGiJISeUGRN 65VRw5O0teTmKDI6LLh6IXJAHMmcSwGcUzYanxpmjgejkGbKV/nXr5Wc+ymmH8jg81yh 1cl5pEiZY7Qvmwh3MX9o6GL4MeOYwshBlyB+Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298269; x=1754903069; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=C/YntZK0scRDzUtpLUdif5ObE8XPBblzRqTujLBoEls=; b=Uc5jGvMk81BOgp7ff0VAWPzsdfDcBJNoMyJdltUxFHbs4s4gL2deZ4HWEq82RY9Wpz siIuokhzndqoy7JqOl04PZbT0xGRtlrA4a8x6mxQH+2gQOf5v2hKFPAh5U3+2RAqcUPb t6Ni4XLHHg3BnnXS9W2Hvd/nd0Ra5AGZBmkw0iBiebg2Nw0870T7myzcJsJSRXSal/zD cCeP85AbS+KLq4rbx4nm4rP5Zj480dNTSqLF2w4QylcEGptb0XWl3wTAWkmaexdWR3kK FPK0NdSCGicQTnGbBR7KM9I8/s/SJgGVlN6ifFmJ1z0nZq6iJNEHwz+lYJ7z6T50YB3U yloQ== X-Forwarded-Encrypted: i=1; AJvYcCXZMUs8sHavN+Mm2pc82kLjq3VqH+MB0dtvw0BaqRvfikSU6Z7hARxHuhPWmSzqWB4TCTW8ASJH8b/hfJM=@vger.kernel.org X-Gm-Message-State: AOJu0YyXWl8GPA7XM3P8wQhS1tuJCTQwk6cDVxxak/gfeFsF3YCB7mxj Q/coBgdKYc2FMCsbn0h6+OCrXJJPkZO2j6D49YZ47TMC6m3emM1TqgxLV9NAoy7cTg== X-Gm-Gg: ASbGncuoWwlVefA3nk9oirLuR7n8TsMJ6LYfg7wZ9IGurqpCA23sBoSLPwlh3Bx29M4 Y6OeaQI/Jkn4jt8wU6qopwiid5E5Qzc5Fb/2YGdNrg+l+at7qZTTG9MKIkqYYVMvT2SstzYKc7J L+gyq4KiDnStUXHc9VgKVK523233kRZ2W2FW4WaYgqlfQSOoNJG+E9YVZlOTcStnRCCksREeoti b2cKlF95wGcEF7tuO8C2JZJp4qUWZVd/2sMez5tNRI3xSaIWXA87ETfFN3kQsTfmhMgeNxHhJSg AXzzc/T4jYye44IgmqUmVT1CwBbbdPnQTwF7aPjfJcNJa2/jX+1UGVvWBkAcB8v5AnYFsBm+UGT m9LShyg14Jf1xxKsXTBymLXxx3HbbCcUDYhK02rR5We/KxQyE0m8fFXrH0c/eO280qGm7CMx0Jc iAlInoh6IWmg/e2KI= X-Google-Smtp-Source: AGHT+IFvegDt8dTEVZTkYDNlKSuxzkDH43Aovq7lgo42X8LYJ+UBemH44YKVdHdMh5C6kMgO4im2Mw== X-Received: by 2002:a05:6402:510d:b0:615:142a:c066 with SMTP id 4fb4d7f45d1cf-615e7172f57mr7139479a12.23.1754298268904; Mon, 04 Aug 2025 02:04:28 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:27 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 04/10] usb: typec: Expose mode priorities via sysfs Date: Mon, 4 Aug 2025 09:03:33 +0000 Message-ID: <20250804090340.3062182-5-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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" This patch introduces new sysfs attributes to allow users to configure and view Type-C mode priorities. `priority`, `usb4_priority` attributes allow users to assign a numeric priority to DisplayPort alt-mode, Thunderbolt alt-mode, and USB4 mode. `mode_priorities` - read-only attribute that displays an ordered list of all modes based on their configured priorities. Signed-off-by: Andrei Kuchynski --- Documentation/ABI/testing/sysfs-class-typec | 33 +++++ drivers/usb/typec/Makefile | 2 +- drivers/usb/typec/class.c | 103 +++++++++++++++- drivers/usb/typec/class.h | 1 + drivers/usb/typec/mode_selection.c | 130 ++++++++++++++++++++ drivers/usb/typec/mode_selection.h | 23 ++++ include/linux/usb/typec_altmode.h | 7 ++ 7 files changed, 295 insertions(+), 4 deletions(-) create mode 100644 drivers/usb/typec/mode_selection.c create mode 100644 drivers/usb/typec/mode_selection.h diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/AB= I/testing/sysfs-class-typec index 38e101c17a00..575dd94f33ab 100644 --- a/Documentation/ABI/testing/sysfs-class-typec +++ b/Documentation/ABI/testing/sysfs-class-typec @@ -162,6 +162,39 @@ Description: Lists the supported USB Modes. The defaul= t USB mode that is used - usb3 (USB 3.2) - usb4 (USB4) =20 + What: /sys/class/typec///priority +Date: July 2025 +Contact: Andrei Kuchynski +Description: + Displays and allows setting the priority for a specific alt-mode. + When read, it shows the current integer priority value. Lower numerical + values indicate higher priority (0 is the highest priority). + If the new value is already in use by another mode, the priority of the + conflicting mode and any subsequent modes will be incremented until they + are all unique. + This attribute is visible only if the kernel supports mode selection. + + What: /sys/class/typec//usb4_priority +Date: July 2025 +Contact: Andrei Kuchynski +Description: + Displays and allows setting the priority for USB4 mode. Its behavior and + priority numbering scheme are identical to the general alt-mode + "priority" attributes. + +What: /sys/class/typec//mode_priorities +Date: July 2025 +Contact: Andrei Kuchynski +Description: This read-only file lists the modes supported by the port, + ordered by their activation priority. It reflects the preferred sequence + the kernel will attempt to activate modes (DisplayPort alt-mode, + Thunderbolt alt-mode, USB4 mode). + This attribute is visible only if the kernel supports mode selection. + + Example values: + - "USB4 Thunderbolt3 DisplayPort" + - "DisplayPort": the port only supports Displayport alt-mode + USB Type-C partner devices (eg. /sys/class/typec/port0-partner/) =20 What: /sys/class/typec/-partner/accessory_mode diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile index 7a368fea61bc..8a6a1c663eb6 100644 --- a/drivers/usb/typec/Makefile +++ b/drivers/usb/typec/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TYPEC) +=3D typec.o -typec-y :=3D class.o mux.o bus.o pd.o retimer.o +typec-y :=3D class.o mux.o bus.o pd.o retimer.o mode_selection.o typec-$(CONFIG_ACPI) +=3D port-mapper.o obj-$(CONFIG_TYPEC) +=3D altmodes/ obj-$(CONFIG_TYPEC_TCPM) +=3D tcpm/ diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index a72325ff099a..414d94c45ab9 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -19,6 +19,7 @@ #include "bus.h" #include "class.h" #include "pd.h" +#include "mode_selection.h" =20 static DEFINE_IDA(typec_index_ida); =20 @@ -445,11 +446,45 @@ svid_show(struct device *dev, struct device_attribute= *attr, char *buf) } static DEVICE_ATTR_RO(svid); =20 +static ssize_t priority_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct typec_altmode *adev =3D to_typec_altmode(dev); + unsigned int val; + int err =3D kstrtouint(buf, 10, &val); + + if (!err) { + err =3D typec_mode_set_priority(to_typec_port(adev->dev.parent), + typec_svid_to_altmode(adev->svid), val); + if (!err) + return size; + } + + return err; +} + +static ssize_t priority_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct typec_altmode *adev =3D to_typec_altmode(dev); + int val; + const int err =3D typec_mode_get_priority(to_typec_port(adev->dev.parent), + typec_svid_to_altmode(adev->svid), &val); + + if (err) + return err; + + return sprintf(buf, "%d\n", val); +} +static DEVICE_ATTR_RW(priority); + static struct attribute *typec_altmode_attrs[] =3D { &dev_attr_active.attr, &dev_attr_mode.attr, &dev_attr_svid.attr, &dev_attr_vdo.attr, + &dev_attr_priority.attr, NULL }; =20 @@ -458,7 +493,7 @@ static umode_t typec_altmode_attr_is_visible(struct kob= ject *kobj, { struct typec_altmode *adev =3D to_typec_altmode(kobj_to_dev(kobj)); =20 - if (attr =3D=3D &dev_attr_active.attr) + if (attr =3D=3D &dev_attr_active.attr) { if (!is_typec_port(adev->dev.parent)) { struct typec_partner *partner =3D to_typec_partner(adev->dev.parent); @@ -469,6 +504,15 @@ static umode_t typec_altmode_attr_is_visible(struct ko= bject *kobj, !adev->ops->activate) return 0444; } + } else if (attr =3D=3D &dev_attr_priority.attr) { + if (is_typec_port(adev->dev.parent)) { + struct typec_port *port =3D to_typec_port(adev->dev.parent); + + if (!port->alt_mode_override) + return 0; + } else + return 0; + } =20 return attr->mode; } @@ -1942,6 +1986,44 @@ static ssize_t orientation_show(struct device *dev, } static DEVICE_ATTR_RO(orientation); =20 +static ssize_t mode_priorities_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return typec_mode_get_priority_list(to_typec_port(dev), buf); +} +static DEVICE_ATTR_RO(mode_priorities); + +static ssize_t usb4_priority_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct typec_port *port =3D to_typec_port(dev); + int val; + const int err =3D typec_mode_get_priority(port, TYPEC_USB4_MODE, &val); + + if (err) + return err; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t usb4_priority_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct typec_port *port =3D to_typec_port(dev); + unsigned int val; + int err =3D kstrtouint(buf, 10, &val); + + if (!err) { + err =3D typec_mode_set_priority(port, TYPEC_USB4_MODE, val); + if (!err) + return size; + } + + return err; +} +static DEVICE_ATTR_RW(usb4_priority); + static struct attribute *typec_attrs[] =3D { &dev_attr_data_role.attr, &dev_attr_power_operation_mode.attr, @@ -1954,6 +2036,8 @@ static struct attribute *typec_attrs[] =3D { &dev_attr_port_type.attr, &dev_attr_orientation.attr, &dev_attr_usb_capability.attr, + &dev_attr_mode_priorities.attr, + &dev_attr_usb4_priority.attr, NULL, }; =20 @@ -1992,6 +2076,13 @@ static umode_t typec_attr_is_visible(struct kobject = *kobj, return 0; if (!port->ops || !port->ops->default_usb_mode_set) return 0444; + } else if (attr =3D=3D &dev_attr_mode_priorities.attr) { + if (!port->alt_mode_override) + return 0; + } else if (attr =3D=3D &dev_attr_usb4_priority.attr) { + if (!port->alt_mode_override || + !(port->cap->usb_capability & USB_CAPABILITY_USB4)) + return 0; } =20 return attr->mode; @@ -2029,6 +2120,7 @@ static void typec_release(struct device *dev) typec_mux_put(port->mux); typec_retimer_put(port->retimer); kfree(port->cap); + typec_mode_selection_destroy(port); kfree(port); } =20 @@ -2496,6 +2588,8 @@ typec_port_register_altmode(struct typec_port *port, to_altmode(adev)->retimer =3D retimer; } =20 + typec_mode_set_priority(port, typec_svid_to_altmode(adev->svid), -1); + return adev; } EXPORT_SYMBOL_GPL(typec_port_register_altmode); @@ -2645,9 +2739,12 @@ struct typec_port *typec_register_port(struct device= *parent, port->con.attach =3D typec_partner_attach; port->con.deattach =3D typec_partner_deattach; =20 - if (cap->usb_capability & USB_CAPABILITY_USB4) + typec_mode_selection_init(port); + + if (cap->usb_capability & USB_CAPABILITY_USB4) { port->usb_mode =3D USB_MODE_USB4; - else if (cap->usb_capability & USB_CAPABILITY_USB3) + typec_mode_set_priority(port, TYPEC_USB4_MODE, -1); + } else if (cap->usb_capability & USB_CAPABILITY_USB3) port->usb_mode =3D USB_MODE_USB3; else if (cap->usb_capability & USB_CAPABILITY_USB2) port->usb_mode =3D USB_MODE_USB2; diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index f05d9201c233..c6467e576569 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -82,6 +82,7 @@ struct typec_port { struct device *usb3_dev; =20 bool alt_mode_override; + struct list_head mode_list; }; =20 #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev) diff --git a/drivers/usb/typec/mode_selection.c b/drivers/usb/typec/mode_se= lection.c new file mode 100644 index 000000000000..9a7185c07d0c --- /dev/null +++ b/drivers/usb/typec/mode_selection.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2025 Google LLC. + */ + +#include +#include +#include +#include "mode_selection.h" +#include "class.h" + +static const char * const mode_names[TYPEC_MODE_MAX] =3D { + [TYPEC_DP_ALTMODE] =3D "DisplayPort", + [TYPEC_TBT_ALTMODE] =3D "Thunderbolt3", + [TYPEC_USB4_MODE] =3D "USB4", +}; + +static const int default_priorities[TYPEC_MODE_MAX] =3D { + [TYPEC_DP_ALTMODE] =3D 2, + [TYPEC_TBT_ALTMODE] =3D 1, + [TYPEC_USB4_MODE] =3D 0, +}; + +/** + * struct mode_selection_state - State tracking for a specific Type-C mode + * @mode: The type of mode this instance represents + * @name: Name string pointer + * @priority: The mode priority. Higher values indicate a more preferred m= ode. + * @list: List head to link this mode state into a prioritized list. + */ +struct mode_selection_state { + enum typec_mode_type mode; + const char *name; + int priority; + struct list_head list; +}; + +/* -----------------------------------------------------------------------= --- */ +/* port 'mode_priorities' attribute */ +void typec_mode_selection_init(struct typec_port *port) +{ + INIT_LIST_HEAD(&port->mode_list); +} + +void typec_mode_selection_destroy(struct typec_port *port) +{ + struct mode_selection_state *ms, *tmp; + + list_for_each_entry_safe(ms, tmp, &port->mode_list, list) { + list_del(&ms->list); + kfree(ms); + } +} + +int typec_mode_set_priority(struct typec_port *port, + const enum typec_mode_type mode, const int priority) +{ + struct mode_selection_state *ms_target =3D NULL; + struct mode_selection_state *ms, *tmp; + + if (mode >=3D TYPEC_MODE_MAX || !mode_names[mode]) + return -EOPNOTSUPP; + + list_for_each_entry_safe(ms, tmp, &port->mode_list, list) { + if (ms->mode =3D=3D mode) { + ms_target =3D ms; + list_del(&ms->list); + break; + } + } + + if (!ms_target) { + ms_target =3D kzalloc(sizeof(struct mode_selection_state), GFP_KERNEL); + if (!ms_target) + return -ENOMEM; + ms_target->mode =3D mode; + ms_target->name =3D mode_names[mode]; + INIT_LIST_HEAD(&ms_target->list); + } + + if (priority >=3D 0) + ms_target->priority =3D priority; + else + ms_target->priority =3D default_priorities[mode]; + + while (ms_target) { + struct mode_selection_state *ms_peer =3D NULL; + + list_for_each_entry(ms, &port->mode_list, list) + if (ms->priority >=3D ms_target->priority) { + if (ms->priority =3D=3D ms_target->priority) + ms_peer =3D ms; + break; + } + + list_add_tail(&ms_target->list, &ms->list); + ms_target =3D ms_peer; + if (ms_target) { + ms_target->priority++; + list_del(&ms_target->list); + } + } + + return 0; +} + +int typec_mode_get_priority(struct typec_port *port, + const enum typec_mode_type mode, int *priority) +{ + struct mode_selection_state *ms; + + list_for_each_entry(ms, &port->mode_list, list) + if (ms->mode =3D=3D mode) { + *priority =3D ms->priority; + return 0; + } + + return -EOPNOTSUPP; +} + +ssize_t typec_mode_get_priority_list(struct typec_port *port, char *buf) +{ + struct mode_selection_state *ms; + ssize_t count =3D 0; + + list_for_each_entry(ms, &port->mode_list, list) + count +=3D sysfs_emit_at(buf, count, "%s ", ms->name); + + return count + sysfs_emit_at(buf, count, "\n"); +} diff --git a/drivers/usb/typec/mode_selection.h b/drivers/usb/typec/mode_se= lection.h new file mode 100644 index 000000000000..151f0f8b6632 --- /dev/null +++ b/drivers/usb/typec/mode_selection.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include + +static inline enum typec_mode_type typec_svid_to_altmode(const u16 svid) +{ + switch (svid) { + case USB_TYPEC_DP_SID: + return TYPEC_DP_ALTMODE; + case USB_TYPEC_TBT_SID: + return TYPEC_TBT_ALTMODE; + } + return TYPEC_MODE_MAX; +} + +void typec_mode_selection_init(struct typec_port *port); +void typec_mode_selection_destroy(struct typec_port *port); +int typec_mode_set_priority(struct typec_port *port, + const enum typec_mode_type mode, const int priority); +int typec_mode_get_priority(struct typec_port *port, + const enum typec_mode_type mode, int *priority); +ssize_t typec_mode_get_priority_list(struct typec_port *port, char *buf); diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_al= tmode.h index b3c0866ea70f..5d14363e02eb 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -145,6 +145,13 @@ enum { =20 #define TYPEC_MODAL_STATE(_state_) ((_state_) + TYPEC_STATE_MODAL) =20 +enum typec_mode_type { + TYPEC_DP_ALTMODE =3D 0, + TYPEC_TBT_ALTMODE, + TYPEC_USB4_MODE, + TYPEC_MODE_MAX, +}; + struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *altmode, enum typec_plug_index index); void typec_altmode_put_plug(struct typec_altmode *plug); --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ed1-f42.google.com (mail-ed1-f42.google.com [209.85.208.42]) (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 59DE0248F4E for ; Mon, 4 Aug 2025 09:04:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298277; cv=none; b=dIBgocyIMdrfYXpH9MIjdIwF8WDTxF8ZRdpHKkYvA6JWBjlKoL+FR9Kfkuovmo2/5Ng2BlEc7f/AGiCGhv2COUDBwfHxxzheFimSHN3lb5CmKQazgFMu7PJD9AiVq+W47kVZUnkuzwGpDzM48HkZRR0vk7P80buHEvkDmA1vpnI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298277; c=relaxed/simple; bh=1yGVPKKthJlH/muny6X7yhCAI1KUFrIYBs43AA5Aokg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ein2ynvz2KlZHHjs07BJq61xbO/b/dXVD3Gz0m/tkv4ckonDzVrxA3mNj7bv8KSrrvPrMdBRYR2Z2ofhKPHbCAKDQ2X9AO7mNbU60OfcxhHYyTM1Ae6pSpA6C8JZsfmo1PF5I8WUiU05tGb1LygSAbioNr7eqjx9MpUHR3vs+3M= 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=hbbVYvoX; arc=none smtp.client-ip=209.85.208.42 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="hbbVYvoX" Received: by mail-ed1-f42.google.com with SMTP id 4fb4d7f45d1cf-61592ff5ebbso7160457a12.3 for ; Mon, 04 Aug 2025 02:04:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298272; x=1754903072; 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=aNFrgeRCwMRLhwjhx4Rv5lD+aMsRG4TVRPHmUSvJSPs=; b=hbbVYvoXg6eMCtyV5HhjK5PNjEXY+muB1ULPsLtKJBhoSIl79aSL1n6V/LDM/43sYY uY7KEJHnbBO9H4mwKSNHEiejr3wuFl8+j4O/1tisY6LhbXpqH0gwEJpLxVCTWET1TL0L MCD0jstnrRdcrtiW/bTUq+8el+3Iw5YonTOp0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298272; x=1754903072; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aNFrgeRCwMRLhwjhx4Rv5lD+aMsRG4TVRPHmUSvJSPs=; b=HsbohNzzkXTBJUKV1pc2sHsKvakWTZrUzVd9p4lN1umGHqpP7wWgzLle7lyKV2gnYZ glbZ9iO9PyDOUQ2Eb+RSU9kFAnbqjGedSaKaVHTPZMrvpBh5z+g+d1fHHt+pWswteyYC t76YsXnaIrDAjfrFBpDNe3/Bcnf5/NqNNZE8OPOHIpvR3SUbBFeMtADPuE7GLWbEobz+ DNrGhNOflBW9qsVbxKo9ZObyM9oUISyk0OZQcvUBt4cTRm6WIkunhRoNtZOBQnYl+Pbv mFH2DqNB2As7wn0gA/ktbqBN4S48ZiHKq2qlHkqcYCyVHAPv7cRP2kuzoIY1BgacCFN/ CG0w== X-Forwarded-Encrypted: i=1; AJvYcCVpndlhfxEoS8EVvnlcIUfxKHd/Pk1uxhbnNB9XNhBN5D0T2Ax/e1cx6zURUkIujP8+fu3RRJAX16J9Ltw=@vger.kernel.org X-Gm-Message-State: AOJu0YxZDpmZobBVDUh5O36v6y94o5xwiLX/+8VVRrF5gQiFO3Q7tUGi yY5gvFxIi74/Qw9kEZvqiCyxgmaLw8VTSYFcOfjwGeMIAPLs03Dch7xVjrFunSn/RA== X-Gm-Gg: ASbGncutImXfUf/q+ZhtYJLNxSeiIoAgJ/fwsevi/nN9w5+Oinn5h72w71SSXZoiVUK toRjeSW5vRATOqgzMBGRyrXfqcbQrdgCqHOu/GAce06IAjBvDOVLCp7gCbEEGlZYFRYtzNzx7UC BfcSI6uMLcnWr7oun33SxNz6elpyPQXkl6yPZAR0bOCFe16hUPfufWk4q5jV1McJjMn8eVw9AxT +sdYmT2930+ZlI5YXzoE/j6N7A3CVb0m0P3BXWZwNAz8qRSc3g91Jzl4zB9xuEeaNIwgm0X6hSh /cMwhiWjB+QtADKqB01vLgPvJuP7iPfsXnAxpS0Rt2bJk0aV94e9/S0gnJ2LE+xtmBapvz8hmFS 5Yj1l4pxllmtc3TeBohvawVNsUWwP1iZgKU8Iy20AnrHhu7rIlIMSsMAdr3fAG3IQeN9kMpVbT+ ekszPjA+DNgJb1LWM= X-Google-Smtp-Source: AGHT+IEW0/btEGJdTsJ4vwLoZORKwTLSPrg3QK8jRK+DiPm6S4hGF5qiKU06prIvAn9GMLYFeiTV5g== X-Received: by 2002:a17:907:8688:b0:ade:43e8:8fa4 with SMTP id a640c23a62f3a-af94008422dmr1001051866b.18.1754298271477; Mon, 04 Aug 2025 02:04:31 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:30 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 05/10] usb: typec: Implement automated mode selection Date: Mon, 4 Aug 2025 09:03:34 +0000 Message-ID: <20250804090340.3062182-6-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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" This patch introduces new sysfs attributes to enable user control over Type-C automated mode selection and provide negotiation feedback. `mode_selection` attribute shows a prioritized list of supported modes with the currently entered mode bracketed. Writing boolean 0 or 1 to this attribute starts or stops the mode selection process, respectively. `entry_result`, `usb4_entry_result` read-only attributes show the result of the last mode selection attempt for a specific mode. Signed-off-by: Andrei Kuchynski --- Documentation/ABI/testing/sysfs-class-typec | 39 ++ drivers/usb/typec/class.c | 95 ++++- drivers/usb/typec/class.h | 12 + drivers/usb/typec/mode_selection.c | 445 ++++++++++++++++++++ drivers/usb/typec/mode_selection.h | 31 ++ include/linux/usb/pd_vdo.h | 2 + include/linux/usb/typec_altmode.h | 5 + 7 files changed, 626 insertions(+), 3 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/AB= I/testing/sysfs-class-typec index 575dd94f33ab..ed89b9880085 100644 --- a/Documentation/ABI/testing/sysfs-class-typec +++ b/Documentation/ABI/testing/sysfs-class-typec @@ -280,6 +280,45 @@ Description: The USB Modes that the partner device sup= ports. The active mode - usb3 (USB 3.2) - usb4 (USB4) =20 +What: /sys/class/typec/-partner/mode_selection +Date: July 2025 +Contact: Andrei Kuchynski +Description: Displays a prioritized list of modes that both the port and t= he + partner support with the currently entered mode bracketed. Parentheses + indicates a mode currently in progress. Modes listed before the active + or in-progress mode have failed. + Automated mode selection is activated by writing boolean 1 to the + file. Conversely, writing boolean 0 will cancel any ongoing selection + process and exit the currently active mode, if any. + This attribute is only present if the kernel supports AP driven mode + entry, where the Application Processor manages USB Type-C alt-modes. + + Example values: + - "USB4 (TBT) DP": USB4 mode entry failed, Thunderbolt alt-mode is in + progress, DisplayPort alt-mode is next. + - "[USB4] TBT DP": USB4 mode is currently active. + +What: /sys/class/typec/-partner//entry_result +Date: July 2025 +Contact: Andrei Kuchynski +Description: This read-only file represents the status for a specific + alt-mode after the last mode selection process. + This attribute is visible only if the kernel supports mode selection. + + Example values: + - "none": No mode selection attempt has occurred for this alt-mode. + - "in progress": The mode entry process is currently underway. + - "active": The alt-mode is currently active. + - "cable failed": The connected cable doesn't support the mode. + - "timeout": Mode entry failed due to a timeout. + - "failed": The attempt to activate the mode failed. + +What: /sys/class/typec/-partner/usb4_entry_result +Date: July 2025 +Contact: Andrei Kuchynski +Description: Represents a status for USB4 mode. Its values are identical to + the general /entry_result attributes. + USB Type-C cable devices (eg. /sys/class/typec/port0-cable/) =20 Note: Electronically Marked Cables will have a device also for one cable p= lug diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 414d94c45ab9..f9515fc594f8 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -479,12 +479,24 @@ static ssize_t priority_show(struct device *dev, } static DEVICE_ATTR_RW(priority); =20 +static ssize_t entry_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct typec_altmode *adev =3D to_typec_altmode(dev); + struct typec_partner *partner =3D to_typec_partner(adev->dev.parent); + + return typec_mode_selection_get_result(partner, + typec_svid_to_altmode(adev->svid), buf); +} +static DEVICE_ATTR_RO(entry_result); + static struct attribute *typec_altmode_attrs[] =3D { &dev_attr_active.attr, &dev_attr_mode.attr, &dev_attr_svid.attr, &dev_attr_vdo.attr, &dev_attr_priority.attr, + &dev_attr_entry_result.attr, NULL }; =20 @@ -508,6 +520,17 @@ static umode_t typec_altmode_attr_is_visible(struct ko= bject *kobj, if (is_typec_port(adev->dev.parent)) { struct typec_port *port =3D to_typec_port(adev->dev.parent); =20 + if (!port->alt_mode_override) + return 0; + } else + return 0; + } else if (attr =3D=3D &dev_attr_entry_result.attr) { + if (is_typec_partner(adev->dev.parent)) { + struct typec_partner *partner =3D + to_typec_partner(adev->dev.parent); + struct typec_port *port =3D + to_typec_port(partner->dev.parent); + if (!port->alt_mode_override) return 0; } else @@ -584,7 +607,7 @@ static void typec_altmode_release(struct device *dev) } =20 const struct device_type typec_altmode_dev_type =3D { - .name =3D "typec_alternate_mode", + .name =3D ALTERNATE_MODE_DEVICE_TYPE_NAME, .groups =3D typec_altmode_groups, .release =3D typec_altmode_release, }; @@ -784,6 +807,44 @@ static ssize_t number_of_alternate_modes_show(struct d= evice *dev, struct device_ } static DEVICE_ATTR_RO(number_of_alternate_modes); =20 +static ssize_t mode_selection_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct typec_partner *partner =3D to_typec_partner(dev); + + return typec_mode_selection_get_active(partner, buf); +} + +static ssize_t mode_selection_store(struct device *dev, struct device_attr= ibute *attr, + const char *buf, size_t size) +{ + struct typec_partner *partner =3D to_typec_partner(dev); + bool start; + int ret =3D kstrtobool(buf, &start); + + if (!ret) { + if (start) + ret =3D typec_mode_selection_start(partner); + else + ret =3D typec_mode_selection_reset(partner); + } + + if (ret) + return ret; + + return size; +} +static DEVICE_ATTR_RW(mode_selection); + +static ssize_t usb4_entry_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return typec_mode_selection_get_result(to_typec_partner(dev), + TYPEC_USB4_MODE, buf); +} +static DEVICE_ATTR_RO(usb4_entry_result); + static struct attribute *typec_partner_attrs[] =3D { &dev_attr_accessory_mode.attr, &dev_attr_supports_usb_power_delivery.attr, @@ -791,6 +852,8 @@ static struct attribute *typec_partner_attrs[] =3D { &dev_attr_type.attr, &dev_attr_usb_mode.attr, &dev_attr_usb_power_delivery_revision.attr, + &dev_attr_mode_selection.attr, + &dev_attr_usb4_entry_result.attr, NULL }; =20 @@ -815,6 +878,16 @@ static umode_t typec_partner_attr_is_visible(struct ko= bject *kobj, struct attrib if (!get_pd_product_type(kobj_to_dev(kobj))) return 0; =20 + if (attr =3D=3D &dev_attr_mode_selection.attr) + if (!port->alt_mode_override) + return 0; + + if (attr =3D=3D &dev_attr_usb4_entry_result.attr) { + if (!port->alt_mode_override || + !(partner->usb_capability & USB_CAPABILITY_USB4)) + return 0; + } + return attr->mode; } =20 @@ -893,8 +966,10 @@ int typec_partner_set_identity(struct typec_partner *p= artner) usb_capability |=3D USB_CAPABILITY_USB2; if (devcap & DEV_USB3_CAPABLE) usb_capability |=3D USB_CAPABILITY_USB3; - if (devcap & DEV_USB4_CAPABLE) + if (devcap & DEV_USB4_CAPABLE) { usb_capability |=3D USB_CAPABILITY_USB4; + typec_mode_selection_add_mode(partner, TYPEC_USB4_MODE); + } } else { usb_capability =3D PD_VDO_DFP_HOSTCAP(id->vdo[0]); } @@ -1014,7 +1089,12 @@ struct typec_altmode * typec_partner_register_altmode(struct typec_partner *partner, const struct typec_altmode_desc *desc) { - return typec_register_altmode(&partner->dev, desc); + struct typec_altmode *alt =3D typec_register_altmode(&partner->dev, desc); + + if (alt) + typec_mode_selection_add_mode(partner, typec_svid_to_altmode(alt->svid)); + + return alt; } EXPORT_SYMBOL_GPL(typec_partner_register_altmode); =20 @@ -1118,6 +1198,8 @@ struct typec_partner *typec_register_partner(struct t= ypec_port *port, typec_partner_link_device(partner, port->usb3_dev); mutex_unlock(&port->partner_link_lock); =20 + typec_mode_selection_add_partner(partner); + return partner; } EXPORT_SYMBOL_GPL(typec_register_partner); @@ -1135,6 +1217,7 @@ void typec_unregister_partner(struct typec_partner *p= artner) if (IS_ERR_OR_NULL(partner)) return; =20 + typec_mode_selection_remove_partner(partner); port =3D to_typec_port(partner->dev.parent); =20 mutex_lock(&port->partner_link_lock); @@ -1403,6 +1486,7 @@ int typec_cable_set_identity(struct typec_cable *cabl= e) } EXPORT_SYMBOL_GPL(typec_cable_set_identity); =20 +static struct typec_partner *typec_get_partner(struct typec_port *port); /** * typec_register_cable - Register a USB Type-C Cable * @port: The USB Type-C Port the cable is connected to @@ -1417,6 +1501,7 @@ struct typec_cable *typec_register_cable(struct typec= _port *port, struct typec_cable_desc *desc) { struct typec_cable *cable; + struct typec_partner *partner; int ret; =20 cable =3D kzalloc(sizeof(*cable), GFP_KERNEL); @@ -1448,6 +1533,10 @@ struct typec_cable *typec_register_cable(struct type= c_port *port, return ERR_PTR(ret); } =20 + partner =3D typec_get_partner(port); + typec_mode_selection_add_cable(partner, cable); + put_device(&partner->dev); + return cable; } EXPORT_SYMBOL_GPL(typec_register_cable); diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index c6467e576569..281dcb6d675c 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -5,6 +5,8 @@ =20 #include #include +#include +#include =20 struct typec_mux; struct typec_switch; @@ -26,6 +28,8 @@ struct typec_cable { enum usb_pd_svdm_ver svdm_version; }; =20 +struct mode_selection_state; + struct typec_partner { struct device dev; unsigned int usb_pd:1; @@ -40,6 +44,12 @@ struct typec_partner { =20 struct usb_power_delivery *pd; =20 + struct delayed_work mode_selection_work; + DECLARE_KFIFO(mode_sequence, struct mode_selection_state *, + roundup_pow_of_two(TYPEC_MODE_MAX)); + struct mutex mode_sequence_lock; + struct mode_selection_state *active_mode; + void (*attach)(struct typec_partner *partner, struct device *dev); void (*deattach)(struct typec_partner *partner, struct device *dev); }; @@ -112,4 +122,6 @@ static inline int typec_link_ports(struct typec_port *c= onnector) { return 0; } static inline void typec_unlink_ports(struct typec_port *connector) { } #endif =20 +#define ALTERNATE_MODE_DEVICE_TYPE_NAME "typec_alternate_mode" + #endif /* __USB_TYPEC_CLASS__ */ diff --git a/drivers/usb/typec/mode_selection.c b/drivers/usb/typec/mode_se= lection.c index 9a7185c07d0c..c7d164478787 100644 --- a/drivers/usb/typec/mode_selection.c +++ b/drivers/usb/typec/mode_selection.c @@ -5,10 +5,19 @@ =20 #include #include +#include +#include #include #include "mode_selection.h" #include "class.h" =20 +/* Timeout for a mode entry attempt, ms */ +static const unsigned int mode_selection_timeout =3D 4000; +/* Delay between mode entry/exit attempts, ms */ +static const unsigned int mode_selection_delay =3D 1000; +/* Maximum retries for mode entry on busy status */ +static const unsigned int mode_entry_attempts =3D 4; + static const char * const mode_names[TYPEC_MODE_MAX] =3D { [TYPEC_DP_ALTMODE] =3D "DisplayPort", [TYPEC_TBT_ALTMODE] =3D "Thunderbolt3", @@ -21,18 +30,59 @@ static const int default_priorities[TYPEC_MODE_MAX] =3D= { [TYPEC_USB4_MODE] =3D 0, }; =20 +/** + * enum ms_state - Specific mode selection states + * @MS_STATE_IDLE: The mode entry process has not started + * @MS_STATE_INPROGRESS: The mode entry process is currently underway + * @MS_STATE_ACTIVE: The mode has been successfully entered + * @MS_STATE_CABLE_FAILED: The connected cable doesn't support the mode + * @MS_STATE_TIMEOUT: Mode entry failed due to a timeout + * @MS_STATE_FAILED: The mode driver reported the error + */ +enum ms_state { + MS_STATE_IDLE =3D 0, + MS_STATE_INPROGRESS, + MS_STATE_ACTIVE, + MS_STATE_CABLE_FAILED, + MS_STATE_TIMEOUT, + MS_STATE_FAILED, + MS_STATE_MAX +}; +static const char * const ms_state_strings[MS_STATE_MAX] =3D { + [MS_STATE_IDLE] =3D "none", + [MS_STATE_INPROGRESS] =3D "in progress", + [MS_STATE_ACTIVE] =3D "active", + [MS_STATE_CABLE_FAILED] =3D "cable failed", + [MS_STATE_TIMEOUT] =3D "timeout", + [MS_STATE_FAILED] =3D "failed", +}; + /** * struct mode_selection_state - State tracking for a specific Type-C mode * @mode: The type of mode this instance represents * @name: Name string pointer * @priority: The mode priority. Higher values indicate a more preferred m= ode. * @list: List head to link this mode state into a prioritized list. + * @partner_supported: Flag indicating if this mode is supported by the pa= rtner + * @cable_supported: Flag indicating if this mode is supported by the cable + * @enter: Flag indicating if the driver is currently attempting to enter = or + * exit the mode + * @attempt_count: Number of times the driver has attempted to enter the m= ode + * @state: The current mode selection state + * @error: The outcome of the last attempt to enter the mode */ struct mode_selection_state { enum typec_mode_type mode; const char *name; int priority; struct list_head list; + + bool partner_supported; + bool cable_supported; + bool enter; + int attempt_count; + enum ms_state state; + int error; }; =20 /* -----------------------------------------------------------------------= --- */ @@ -128,3 +178,398 @@ ssize_t typec_mode_get_priority_list(struct typec_por= t *port, char *buf) =20 return count + sysfs_emit_at(buf, count, "\n"); } + +/* -----------------------------------------------------------------------= --- */ +/* partner 'mod_selection' attribute */ + +/** + * mode_selection_next() - Process mode selection results and schedule next + * action + * @partner: pointer to the partner structure + * @ms: pointer to active mode_selection_state object that is on top in + * mode_sequence FIFO. + * + * The mutex protecting the mode_sequence FIFO must be held by the caller + * when invoking this function. + * + * This function evaluates the outcome of the previous mode entry or exit + * attempt. Based on this result, it determines the next mode to process a= nd + * schedules `mode_selection_work()` if further actions are required. + * + * If the previous mode entry was successful, the mode selection sequence = is + * considered complete for the current cycle. + * + * If the previous mode entry failed, this function schedules + * `mode_selection_work()` to attempt exiting the mode that was partially + * activated but not fully entered. + * + * If the previous operation was an exit (after a failed entry attempt), + * `mode_selection_next()` then advances the internal list of candidate + * modes to determine the next mode to enter. + */ +static void mode_selection_next( + struct typec_partner *partner, struct mode_selection_state *ms) + + __must_hold(&partner->mode_sequence_lock) +{ + if (!ms->enter) { + kfifo_skip(&partner->mode_sequence); + } else if (ms->state =3D=3D MS_STATE_INPROGRESS && !ms->error) { + ms->state =3D MS_STATE_ACTIVE; + partner->active_mode =3D ms; + kfifo_reset(&partner->mode_sequence); + } else { + if (ms->error) { + ms->state =3D MS_STATE_FAILED; + dev_dbg(&partner->dev, "%s: entry mode error %pe\n", + ms->name, ERR_PTR(ms->error)); + } + if (ms->error !=3D -EBUSY || ms->attempt_count >=3D mode_entry_attempts) + ms->enter =3D false; + } + + if (!kfifo_is_empty(&partner->mode_sequence)) + schedule_delayed_work(&partner->mode_selection_work, + msecs_to_jiffies(mode_selection_delay)); +} + +static void mode_selection_complete(struct typec_partner *partner, + const enum typec_mode_type mode, const int error) +{ + struct mode_selection_state *ms; + + mutex_lock(&partner->mode_sequence_lock); + if (kfifo_peek(&partner->mode_sequence, &ms)) { + if (ms->mode =3D=3D mode && ms->state =3D=3D MS_STATE_INPROGRESS) { + ms->error =3D error; + cancel_delayed_work(&partner->mode_selection_work); + mode_selection_next(partner, ms); + } + } + mutex_unlock(&partner->mode_sequence_lock); +} + +void typec_mode_selection_altmode_complete(struct typec_altmode *alt, + const int error) +{ + mode_selection_complete(to_typec_partner(alt->dev.parent), + typec_svid_to_altmode(alt->svid), error); +} +EXPORT_SYMBOL_GPL(typec_mode_selection_altmode_complete); + +void typec_mode_selection_usb4_complete(struct typec_partner *partner, + const int error) +{ + mode_selection_complete(partner, TYPEC_USB4_MODE, error); +} +EXPORT_SYMBOL_GPL(typec_mode_selection_usb4_complete); + +static void mode_selection_activate_usb4_mode(struct typec_partner *partne= r, + struct mode_selection_state *ms) +{ + struct typec_port *port =3D to_typec_port(partner->dev.parent); + int error =3D -EOPNOTSUPP; + + if (port->ops && port->ops->enter_usb_mode) { + if (ms->enter && port->usb_mode !=3D USB_MODE_USB4) + error =3D -EPERM; + else + error =3D port->ops->enter_usb_mode(port, + ms->enter ? USB_MODE_USB4 : USB_MODE_USB3); + } + + if (ms->enter) + ms->error =3D error; +} + +static int mode_selection_activate_altmode(struct device *dev, void *data) +{ + struct typec_altmode *alt =3D to_typec_altmode(dev); + struct mode_selection_state *ms =3D (struct mode_selection_state *)data; + int error =3D -ENODEV; + int ret =3D 0; + + if (!strcmp(dev->type->name, ALTERNATE_MODE_DEVICE_TYPE_NAME)) { + if (ms->mode =3D=3D typec_svid_to_altmode(alt->svid)) { + if (alt->ops && alt->ops->activate) + error =3D alt->ops->activate(alt, ms->enter); + else + error =3D -EOPNOTSUPP; + ret =3D 1; + } + } + + if (ms->enter) + ms->error =3D error; + + return ret; +} + +static void mode_selection_activate_mode(struct typec_partner *partner, + struct mode_selection_state *ms) +{ + if (ms->enter) + ms->attempt_count++; + + if (ms->mode =3D=3D TYPEC_USB4_MODE) + mode_selection_activate_usb4_mode(partner, ms); + else + device_for_each_child(&partner->dev, ms, + mode_selection_activate_altmode); +} + +/** + * mode_selection_work() - Activate entry into the upcoming mode + * @work: work structure + * + * This function works in conjunction with `mode_selection_next()`. + * It attempts to activate the next mode in the selection sequence. + * + * If the mode activation (`mode_selection_activate_mode()`) fails, + * `mode_selection_next()` will be called to initiate a new selection cycl= e. + * + * Otherwise, the state is set to MS_STATE_INPROGRESS, and + * `mode_selection_work()` is scheduled for a subsequent entry after a tim= eout + * period. The alternate mode driver is expected to call back with the act= ual + * mode entry result. Upon this callback, `mode_selection_next()` will det= ermine + * the subsequent mode and re-schedule `mode_selection_work()`. + */ +static void mode_selection_work(struct work_struct *work) +{ + struct typec_partner *partner =3D container_of(work, struct typec_partner, + mode_selection_work.work); + struct mode_selection_state *ms; + + mutex_lock(&partner->mode_sequence_lock); + if (kfifo_peek(&partner->mode_sequence, &ms)) { + if (ms->state =3D=3D MS_STATE_INPROGRESS) { + ms->state =3D MS_STATE_TIMEOUT; + mode_selection_next(partner, ms); + } else { + mode_selection_activate_mode(partner, ms); + + if (ms->enter && !ms->error) { + ms->state =3D MS_STATE_INPROGRESS; + schedule_delayed_work(&partner->mode_selection_work, + msecs_to_jiffies(mode_selection_timeout)); + } else + mode_selection_next(partner, ms); + } + } + mutex_unlock(&partner->mode_sequence_lock); +} + +static void mode_selection_clear_results(struct typec_partner *partner) +{ + struct typec_port *port =3D to_typec_port(partner->dev.parent); + struct mode_selection_state *ms; + + list_for_each_entry(ms, &port->mode_list, list) { + ms->enter =3D true; + ms->state =3D MS_STATE_IDLE; + ms->error =3D 0; + ms->attempt_count =3D 0; + } + + kfifo_reset(&partner->mode_sequence); + partner->active_mode =3D NULL; +} + +void typec_mode_selection_add_partner(struct typec_partner *partner) +{ + struct typec_port *port =3D to_typec_port(partner->dev.parent); + struct mode_selection_state *ms; + + list_for_each_entry(ms, &port->mode_list, list) { + ms->partner_supported =3D false; + ms->cable_supported =3D false; + } + + INIT_KFIFO(partner->mode_sequence); + mutex_init(&partner->mode_sequence_lock); + mode_selection_clear_results(partner); + INIT_DELAYED_WORK(&partner->mode_selection_work, mode_selection_work); +} + +void typec_mode_selection_add_mode(struct typec_partner *partner, + const enum typec_mode_type mode) +{ + struct typec_port *port =3D to_typec_port(partner->dev.parent); + struct mode_selection_state *ms; + + list_for_each_entry(ms, &port->mode_list, list) { + if (ms->mode =3D=3D mode) { + ms->partner_supported =3D true; + break; + } + } +} + +void typec_mode_selection_add_cable(struct typec_partner *partner, + struct typec_cable *cable) +{ + struct typec_port *port =3D to_typec_port(partner->dev.parent); + struct mode_selection_state *ms; + const u32 id_header =3D cable->identity->id_header; + const u32 vdo1 =3D cable->identity->vdo[0]; + const u32 type =3D PD_IDH_PTYPE(id_header); + const u32 speed =3D VDO_TYPEC_CABLE_SPEED(vdo1); + /* + * Some USB devices supporting DisplayPort lack valid cable VDO. + * Allow only DP mode in this case. + */ + bool capability[TYPEC_MODE_MAX] =3D { + [TYPEC_DP_ALTMODE] =3D true, + [TYPEC_TBT_ALTMODE] =3D false, + [TYPEC_USB4_MODE] =3D false, + }; + + if (type =3D=3D IDH_PTYPE_PCABLE) { + capability[TYPEC_DP_ALTMODE] =3D (speed > CABLE_USB2_ONLY); + capability[TYPEC_TBT_ALTMODE] =3D (speed > CABLE_USB2_ONLY); + capability[TYPEC_USB4_MODE] =3D (speed > CABLE_USB2_ONLY); + } else if (type =3D=3D IDH_PTYPE_ACABLE) { + const u32 vdo2 =3D cable->identity->vdo[1]; + const u32 version =3D VDO_TYPEC_CABLE_VERSION(vdo1); + const bool usb4_support =3D VDO_TYPEC_CABLE_USB4_SUPP(vdo2); + const bool modal_support =3D PD_IDH_MODAL_SUPP(id_header); + + capability[TYPEC_DP_ALTMODE] =3D modal_support; + capability[TYPEC_TBT_ALTMODE] =3D true; + if (version =3D=3D CABLE_VDO_VER1_3) + capability[TYPEC_USB4_MODE] =3D usb4_support; + else + capability[TYPEC_USB4_MODE] =3D modal_support; + } + + list_for_each_entry(ms, &port->mode_list, list) + ms->cable_supported =3D capability[ms->mode]; +} + +void typec_mode_selection_remove_partner(struct typec_partner *partner) +{ + mutex_lock(&partner->mode_sequence_lock); + kfifo_reset(&partner->mode_sequence); + mutex_unlock(&partner->mode_sequence_lock); + + cancel_delayed_work_sync(&partner->mode_selection_work); + mutex_destroy(&partner->mode_sequence_lock); +} + +/** + * typec_mode_selection_start() - Starts the mode selection process. + * @partner: pointer to the partner structure + * + * This function populates a 'mode_sequence' FIFO with pointers to + * `struct mode_selection_state` instances. The sequence is generated base= d on + * partner/cable capabilities and prioritized according to the port's sett= ings. + */ +int typec_mode_selection_start(struct typec_partner *partner) +{ + struct typec_port *port =3D to_typec_port(partner->dev.parent); + struct mode_selection_state *ms; + int ret =3D 0; + + mutex_lock(&partner->mode_sequence_lock); + + if (!kfifo_is_empty(&partner->mode_sequence)) + ret =3D -EINPROGRESS; + else if (partner->active_mode) + ret =3D -EALREADY; + else { + mode_selection_clear_results(partner); + + list_for_each_entry(ms, &port->mode_list, list) { + if (ms->partner_supported) { + if (ms->cable_supported) + kfifo_put(&partner->mode_sequence, ms); + else + ms->state =3D MS_STATE_CABLE_FAILED; + } + } + + if (kfifo_peek(&partner->mode_sequence, &ms)) + schedule_delayed_work(&partner->mode_selection_work, 0); + } + + mutex_unlock(&partner->mode_sequence_lock); + + return ret; +} + +/** + * typec_mode_selection_reset() - Reset the mode selection process. + * @partner: pointer to the partner structure + * + * This function cancels ongoing mode selection and exits the currently ac= tive + * mode, if present. + * It returns -EINPROGRESS when a mode exit is already scheduled, or a mode + * entry is ongoing, indicating that the reset cannot immediately complete. + */ +int typec_mode_selection_reset(struct typec_partner *partner) +{ + struct mode_selection_state *ms; + + mutex_lock(&partner->mode_sequence_lock); + if (kfifo_peek(&partner->mode_sequence, &ms)) { + kfifo_reset(&partner->mode_sequence); + + if (!ms->enter || ms->state !=3D MS_STATE_IDLE) { + ms->attempt_count =3D mode_entry_attempts; + kfifo_put(&partner->mode_sequence, ms); + mutex_unlock(&partner->mode_sequence_lock); + + return -EINPROGRESS; + } + } + + if (partner->active_mode) { + partner->active_mode->enter =3D false; + mode_selection_activate_mode(partner, partner->active_mode); + } + mode_selection_clear_results(partner); + mutex_unlock(&partner->mode_sequence_lock); + + return 0; +} + +int typec_mode_selection_get_active(struct typec_partner *partner, char *b= uf) +{ + struct typec_port *port =3D to_typec_port(partner->dev.parent); + struct mode_selection_state *ms, *running_ms; + ssize_t count =3D 0; + + mutex_lock(&partner->mode_sequence_lock); + if (!kfifo_peek(&partner->mode_sequence, &running_ms)) + running_ms =3D NULL; + + list_for_each_entry(ms, &port->mode_list, list) { + if (ms->partner_supported) { + if (ms->state =3D=3D MS_STATE_ACTIVE) + count +=3D sysfs_emit_at(buf, count, "[%s] ", ms->name); + else if (ms =3D=3D running_ms) + count +=3D sysfs_emit_at(buf, count, "(%s) ", ms->name); + else + count +=3D sysfs_emit_at(buf, count, "%s ", ms->name); + } + } + mutex_unlock(&partner->mode_sequence_lock); + + if (count) + count +=3D sysfs_emit_at(buf, count, "\n"); + + return count; +} + +int typec_mode_selection_get_result(struct typec_partner *partner, + const enum typec_mode_type mode, char *buf) +{ + struct typec_port *port =3D to_typec_port(partner->dev.parent); + struct mode_selection_state *ms; + + list_for_each_entry(ms, &port->mode_list, list) + if (ms->mode =3D=3D mode) + return sysfs_emit(buf, "%s\n", ms_state_strings[ms->state]); + + return -EOPNOTSUPP; +} diff --git a/drivers/usb/typec/mode_selection.h b/drivers/usb/typec/mode_se= lection.h index 151f0f8b6632..2238a7200eae 100644 --- a/drivers/usb/typec/mode_selection.h +++ b/drivers/usb/typec/mode_selection.h @@ -21,3 +21,34 @@ int typec_mode_set_priority(struct typec_port *port, int typec_mode_get_priority(struct typec_port *port, const enum typec_mode_type mode, int *priority); ssize_t typec_mode_get_priority_list(struct typec_port *port, char *buf); + +/** + * The mode selection process follows a lifecycle tied to the USB-C partner + * device. The API is designed to first build a set of desired modes and t= hen + * trigger the selection process. The expected sequence of calls is as fol= lows: + * + * Creation and Configuration: + * call typec_mode_selection_add_partner() when the partner device is bein= g set + * up. After creation, call typec_mode_selection_add_mode() and + * typec_mode_selection_add_cable() to define the parameters for the + * selection process. + * + * Execution: + * Call typec_mode_selection_start() to trigger the mode selection. + * Call typec_mode_selection_reset() to prematurely stop the selection + * process and clear any stored results. + * + * Destruction: + * Before destroying a partner, call typec_mode_selection_remove_partner() + */ +void typec_mode_selection_add_partner(struct typec_partner *partner); +void typec_mode_selection_remove_partner(struct typec_partner *partner); +int typec_mode_selection_start(struct typec_partner *partner); +int typec_mode_selection_reset(struct typec_partner *partner); +void typec_mode_selection_add_mode(struct typec_partner *partner, + const enum typec_mode_type mode); +void typec_mode_selection_add_cable(struct typec_partner *partner, + struct typec_cable *cable); +int typec_mode_selection_get_active(struct typec_partner *partner, char *b= uf); +int typec_mode_selection_get_result(struct typec_partner *partner, + const enum typec_mode_type mode, char *buf); diff --git a/include/linux/usb/pd_vdo.h b/include/linux/usb/pd_vdo.h index 5c48e8a81403..20bcf37ad634 100644 --- a/include/linux/usb/pd_vdo.h +++ b/include/linux/usb/pd_vdo.h @@ -439,6 +439,8 @@ | (trans) << 11 | (phy) << 10 | (ele) << 9 | (u4) << 8 \ | ((hops) & 0x3) << 6 | (u2) << 5 | (u32) << 4 | (lane) << 3 \ | (iso) << 2 | (gen)) +#define VDO_TYPEC_CABLE_VERSION(vdo) (((vdo) >> 21) & 0x7) +#define VDO_TYPEC_CABLE_USB4_SUPP(vdo) (((vdo) & BIT(8)) =3D=3D ACAB2_USB4= _SUPP) =20 /* * AMA VDO (PD Rev2.0) diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_al= tmode.h index 5d14363e02eb..f7fd51b4c23e 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -225,4 +225,9 @@ void typec_altmode_unregister_driver(struct typec_altmo= de_driver *drv); module_driver(__typec_altmode_driver, typec_altmode_register_driver, \ typec_altmode_unregister_driver) =20 +void typec_mode_selection_altmode_complete(struct typec_altmode *alt, + const int result); +void typec_mode_selection_usb4_complete(struct typec_partner *partner, + const int result); + #endif /* __USB_TYPEC_ALTMODE_H */ --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) (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 E89182472AA for ; Mon, 4 Aug 2025 09:04:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298277; cv=none; b=ZdI4OqBM0LDBel5utk5jpopwORcpYj4YlwZrwn2Yr2uzpnd78cxsOD4kj9BPy6bYa4uygr0n5wDoQpcIBzsKqxX+k4Guzn+UtOkFUelJZ9TtybUK53FdtELkgNMMG5615wMFZvP+2TbkwYLdnjUQI2Xvre2sYoOAk8ZS+AhwaVo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298277; c=relaxed/simple; bh=Wim6/hhsGkzpmyBteC6lxKug+x1Hl++2A1SnnryflnA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bf8WgmlU+IVMcZ2wwjY73s01ymEFNvV/BnmrsNI9lBVl1lc7E9w4BrsOIN215H4tZugNuOsiXt7I8qdD8ufe19pD90Jdo/Zz6CbrHHa1rFJ8D00BxDMX9sI9mXhGwiuUz//Yl0GSuFCgdFm/nkc5jiL8wNX4Ybnuu2Ku5JxX1jU= 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=aU+J1y3S; arc=none smtp.client-ip=209.85.218.47 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="aU+J1y3S" Received: by mail-ej1-f47.google.com with SMTP id a640c23a62f3a-ae3b336e936so633590966b.3 for ; Mon, 04 Aug 2025 02:04:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298274; x=1754903074; 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=JirWTL5DD5i/aaLwZXtRPh+upuNujZxtHnxy4nebniE=; b=aU+J1y3SCsZX9AbJajnkwaIZFEJVttms3UzXGs/o/Pw6x5h2Fyzw0g+4P5BCZR/nS/ LH57nrj5H1It43YIvDK95iA8+6X5zrz1854i9BrdK33xvl51mlVpiZxT4zAc8yHKU0WF Lq7XWCJijwdxe6e3aLBsHVOlqG/pqmIvKDqgo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298274; x=1754903074; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JirWTL5DD5i/aaLwZXtRPh+upuNujZxtHnxy4nebniE=; b=guBQ22/RQYeJVCd5TgUyEM0qyVr0DFMIDkEl0VFvJ0pOTbccQbgnXb+g82jkL4IB+q AmxFtwJNzm/WxIp4KUo/IpWhyW3gzaNYI2OSAFXZMbel/RXqF7J6FXQtSqbtZA1OWirw f6yGepiLs8Ynxq8gXBT2My9vbi7FzliFsqlAVSgPNhPFx0BmkWA/vgQwmNfrIf+/5zqA GYMvjoILNCCADlAJdIuRPREzgdFII/ChZtPgfTTqs05btQEMOePoBWzvqvVTsQmqsFiV VrF3gntkBoNcFOi6Yt2Mi+OBQQyTQi5TWwHk2H/DJtXlofzxS0CBPHVh6j3JQYAxbOE7 bAsQ== X-Forwarded-Encrypted: i=1; AJvYcCWifgPyGVuWmNybWAoII2qiT/PNkCAtMXxnuVzub+6pHgRxnNpLYulKnQgeoGP8lZmZIELFunMDA4dwZ8M=@vger.kernel.org X-Gm-Message-State: AOJu0Yxz3Q+ViJAoVsS+yG86uXr3kS8M4xgFwngF2Od+070UOgYF1j8N 94ttl3wxqOgOGuwIc/GfiOl6oFgU/NykbyEMPuSc9IH2J2f2641CrS2PBYb5TXhtgQ== X-Gm-Gg: ASbGncsnix4G4HLp6jnTlCOWjhxlIlJeXQIaQ9sJkagqgGjzRbJ3kSXRJeANVBc0DOa zZuF9bQA/285gp07KaZ0Mpvx/hLDeCrfp3h8LqKRltTrItjf+866C5m96pOVVBGlnsy+fDgZP5y MOKNtjdmJM3fGxkejcQ8d/8VvUrNZQyCKB+KeV2IBWQaDl6ipkfxYtgF2QJFXcCEzg/vvkzWuLz SuPP/XKb/iFpTR/hnBmcMskE1oklbuq/c9WtKgrRrkQuMCjmb5toUPyyOTU7w3NRN7HgvxYUXxM QCGsGOER96n8UPjNppUhPe4zsB5Ji2lRWEJvimx2nDhKe5fFzuEmTIj3A5TM5u1ZbllV/RfOf+T cGHrImA1Mz0PC40bWFBAKyqzA6BFm6bScvxFueoTtVrIb1sHtfKHZZ6a76Q7lFSftMQP0WTiQU8 hycU5hLQ1WQ9qEVck= X-Google-Smtp-Source: AGHT+IEXwVnGXEwJmvwIKQ+9TglwzCM+Cwf+cZbxJgv6w4qbaGweSEZddpXpmziYmO2DBNvTXArTGA== X-Received: by 2002:a17:907:948c:b0:ae6:abe9:4daa with SMTP id a640c23a62f3a-af940079146mr950414766b.27.1754298274157; Mon, 04 Aug 2025 02:04:34 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:33 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 06/10] usb: typec: Report altmode entry status via callback Date: Mon, 4 Aug 2025 09:03:35 +0000 Message-ID: <20250804090340.3062182-7-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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 Type-C mode selection logic requires feedback on the result of an alternate mode entry attempt. Call the `typec_mode_selection_altmode_complete()` callback to provide this final success or failure status. Signed-off-by: Andrei Kuchynski --- drivers/usb/typec/altmodes/displayport.c | 17 +++++++++++++++-- drivers/usb/typec/altmodes/thunderbolt.c | 8 ++++++++ include/linux/usb/typec_tbt.h | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/a= ltmodes/displayport.c index 1dcb77faf85d..cac78d995047 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -293,16 +293,20 @@ static void dp_altmode_work(struct work_struct *work) header =3D DP_HEADER(dp, svdm_version, DP_CMD_STATUS_UPDATE); vdo =3D 1; ret =3D typec_altmode_vdm(dp->alt, header, &vdo, 2); - if (ret) + if (ret) { dev_err(&dp->alt->dev, "unable to send Status Update command (%d)\n", ret); + typec_mode_selection_altmode_complete(dp->alt, ret); + } break; case DP_STATE_CONFIGURE: ret =3D dp_altmode_configure_vdm(dp, dp->data.conf); - if (ret) + if (ret) { dev_err(&dp->alt->dev, "unable to send Configure command (%d)\n", ret); + typec_mode_selection_altmode_complete(dp->alt, ret); + } break; case DP_STATE_CONFIGURE_PRIME: ret =3D dp_altmode_configure_vdm_cable(dp, dp->data_prime.conf); @@ -371,6 +375,7 @@ static int dp_altmode_vdm(struct typec_altmode *alt, int cmd_type =3D PD_VDO_CMDT(hdr); int cmd =3D PD_VDO_CMD(hdr); int ret =3D 0; + int entry_result =3D 0; =20 mutex_lock(&dp->lock); =20 @@ -414,10 +419,12 @@ static int dp_altmode_vdm(struct typec_altmode *alt, switch (cmd) { case DP_CMD_STATUS_UPDATE: dp->state =3D DP_STATE_EXIT; + entry_result =3D *(int *)vdo; break; case DP_CMD_CONFIGURE: dp->data.conf =3D 0; ret =3D dp_altmode_configured(dp); + entry_result =3D *(int *)vdo; break; default: break; @@ -432,6 +439,12 @@ static int dp_altmode_vdm(struct typec_altmode *alt, =20 err_unlock: mutex_unlock(&dp->lock); + + if (!entry_result) + entry_result =3D ret; + if (entry_result || cmd =3D=3D DP_CMD_CONFIGURE) + typec_mode_selection_altmode_complete(dp->alt, entry_result); + return ret; } =20 diff --git a/drivers/usb/typec/altmodes/thunderbolt.c b/drivers/usb/typec/a= ltmodes/thunderbolt.c index 6eadf7835f8f..bbba3c6bc8b8 100644 --- a/drivers/usb/typec/altmodes/thunderbolt.c +++ b/drivers/usb/typec/altmodes/thunderbolt.c @@ -214,6 +214,7 @@ static int tbt_altmode_vdm(struct typec_altmode *alt, struct typec_thunderbolt_data data; int cmd_type =3D PD_VDO_CMDT(hdr); int cmd =3D PD_VDO_CMD(hdr); + int entry_result =3D 0; =20 mutex_lock(&tbt->lock); =20 @@ -248,6 +249,10 @@ static int tbt_altmode_vdm(struct typec_altmode *alt, switch (cmd) { case CMD_ENTER_MODE: dev_warn(&alt->dev, "Enter Mode refused\n"); + entry_result =3D *(int *)vdo; + break; + case TBT_CMD_STATUS_UPDATE: + entry_result =3D *(int *)vdo; break; default: break; @@ -262,6 +267,9 @@ static int tbt_altmode_vdm(struct typec_altmode *alt, =20 mutex_unlock(&tbt->lock); =20 + if (entry_result || cmd =3D=3D TBT_CMD_STATUS_UPDATE) + typec_mode_selection_altmode_complete(alt, entry_result); + return 0; } =20 diff --git a/include/linux/usb/typec_tbt.h b/include/linux/usb/typec_tbt.h index 55dcea12082c..57cbda5292bb 100644 --- a/include/linux/usb/typec_tbt.h +++ b/include/linux/usb/typec_tbt.h @@ -24,6 +24,9 @@ struct typec_thunderbolt_data { u32 enter_vdo; }; =20 +/* TBT3 alt mode specific commands */ +#define TBT_CMD_STATUS_UPDATE VDO_CMD_VENDOR(0) + /* TBT3 Device Discover Mode VDO bits */ #define TBT_MODE BIT(0) #define TBT_ADAPTER(_vdo_) FIELD_GET(BIT(16), _vdo_) --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) (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 D6E2724EA85 for ; Mon, 4 Aug 2025 09:04:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298282; cv=none; b=qIaUFRWSYDSc1/azIKdJQ+s/do05FnAS7f/psA2UvN5z6EXoMxO7lc29+7DGDgsDHSGGD4q0557I3CYntssDbR769es4cOyTD6RrBOTKwFbbPXyETIN8NAIjDBk9nsFwYL/aFHw1Vt9mMzeVNAsRr6ifJroF1MpG/w48O3F37G0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298282; c=relaxed/simple; bh=lGxWrmyJi7QQe0IzSfeCLytqae6M3U2caSjouup0SQ4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FlD0aAAwWYMXosb/moXCPP/Vt4L/8HrqSxkGehhChix8O/KBiDeTmgYIuswlXhpoeXzYpFYirbX0rTtTtuPBKI8Yfyz0lqpU4zSPR/7Ln7VTDDbfbgvOLyQ9myLEWCjpaQa6yBBppTQa0SJ7Bbq+KR6GBOv10BYwoblzDaPQi18= 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=KnM0i9+I; arc=none smtp.client-ip=209.85.218.54 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="KnM0i9+I" Received: by mail-ej1-f54.google.com with SMTP id a640c23a62f3a-af968aa2de4so117526366b.1 for ; Mon, 04 Aug 2025 02:04:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298279; x=1754903079; 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=fwNnM2nFXT5vCpq6GQAtc8w4BljRfhoqKtZx8NfXTfY=; b=KnM0i9+IYqWS7cCwt0nKUZ9IR3Fjrd5yFGTtHygPlWnL27Y0BSSu0wBBCS4LZXiqvV AuuCZr+w2en7snRfIcsmPb6473CtbzNbwVy3JS8N+oLIvDMBXB5tBpz+HXrzkkKapZJQ Gn6e5hVBhTkm0EwZKtpAqUFrAn/vnsri+snBI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298279; x=1754903079; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fwNnM2nFXT5vCpq6GQAtc8w4BljRfhoqKtZx8NfXTfY=; b=KwyJBLF4NRhdeO9dGX1y3n2RNJqCX9ppZkXL+Cigf9xPxuVMEZRDrWhNlvodKg3LoA 6TunAYQpk31HqopO71tZ4And9w3NRvO0XRh0HRQyMPD/MeqoewAq4LngnK4zJ2KoWRfP Hhi7fS2aJeM1v/GNTGvZd8Ndp5OHvdfumqSCNoRfs/NCDeZCTf/aE0zxDyCLWMzjwrLz K9r6stdtvc76nLZloswYGd2gAPW7gho1ZFKTQZlGkKxTGxENlITI4sKk9ODZ+PeFcIHj oQk1vrT9t/B3s3i0I8ka0hQBJ+XD33mKZyNWIlyCKC9+onfciG6jpROpXmJq8OLUH1wi AR4w== X-Forwarded-Encrypted: i=1; AJvYcCWSRdKny6KhqPJe+DDK6BQ6p46wl6p+7oootVC92fAOSQDvH+ZZJRE2+ezixKoilaubIkV0hPtWtv2vuz4=@vger.kernel.org X-Gm-Message-State: AOJu0YzpdniWrNCCTGSGfUEuzd/x/GCMk7tN44jAzGWqwXi4D3j1a2Eu SbOrjj8yLlfyPngfP1Q6V+oUUgGoPKK8wWH3uEzccFVDD/Jw2DNpqJKjJ1ApWrLOiw== X-Gm-Gg: ASbGncuctjjlJCniQikQe+KslEiqY6DNYXTwCcUZVMMgj5A9j02y4/np5abgEBFfv3o ikusfj5Pzwp71uB5P9ztdeeV5cXYMOmSvQ4OhlGIgAlk+EBSt46U/3vjMEbvpVhV75JiOxl/7KM y4mQbW1pqBc2zXUv+InxLtVNkd8D6uwd3zuRIaf47FpKFKS5/VMX6ThppM6UNkVOix4LuT1H6K9 9Oa3D3kAxz4DyY+sKrVM3XUborpWR2hZ/jh2+Cgif6bXs6vKTgSgbkn0K85MAx8bOifvLecKUVx IroPyWnZkCoj0QVQ/TC3z9R3QrTrdcRA8jVwMBIgLtnHsCjFMsxi6U/aEhpqJ0DG3gVuGOYh9Ji 3rILYEvyc6QEmu2A+y0ElbtJ8ENdVnuL77I6gh2VGU5/kYYGMg3OOEcF0AOMMY/4URqrilXJlnx WOOJirTcBksNTNuXI= X-Google-Smtp-Source: AGHT+IFDY6Eti/U0HvJUllLufsYb1TLIXF6CEqk3Nsb18AYq8jRe68qPhRYRsXxRYg9IeMMo3fetyA== X-Received: by 2002:a17:907:7f0f:b0:ae0:ded9:7f31 with SMTP id a640c23a62f3a-af94001f8dbmr979021766b.20.1754298279104; Mon, 04 Aug 2025 02:04:39 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:38 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 07/10] usb: typec: ucsi: displayport: Propagate DP altmode entry result Date: Mon, 4 Aug 2025 09:03:36 +0000 Message-ID: <20250804090340.3062182-8-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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" Reporting the error code via VDM back to the Type-C mode selection logic allows the detailed result to be propagated to user space. Signed-off-by: Andrei Kuchynski --- drivers/usb/typec/ucsi/displayport.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/ucsi/displayport.c b/drivers/usb/typec/ucsi/= displayport.c index 8aae80b457d7..47c28646cfa9 100644 --- a/drivers/usb/typec/ucsi/displayport.c +++ b/drivers/usb/typec/ucsi/displayport.c @@ -234,14 +234,18 @@ static int ucsi_displayport_vdm(struct typec_altmode = *alt, =20 switch (cmd) { case DP_CMD_STATUS_UPDATE: - if (ucsi_displayport_status_update(dp)) + dp->data.error =3D ucsi_displayport_status_update(dp); + if (dp->data.error) { + dp->vdo_data =3D &dp->data.error; dp->header |=3D VDO_CMDT(CMDT_RSP_NAK); - else + } else dp->header |=3D VDO_CMDT(CMDT_RSP_ACK); break; case DP_CMD_CONFIGURE: dp->data.conf =3D *data; - if (ucsi_displayport_configure(dp)) { + dp->data.error =3D ucsi_displayport_configure(dp); + if (dp->data.error) { + dp->vdo_data =3D &dp->data.error; dp->header |=3D VDO_CMDT(CMDT_RSP_NAK); } else { dp->header |=3D VDO_CMDT(CMDT_RSP_ACK); --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) (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 67CAD24E4A1 for ; Mon, 4 Aug 2025 09:04:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298286; cv=none; b=HLDKk8ImpROq1ZcR1PCYVWYqNBlFD8djoDznO4rtACHDfTbsLxCdrnLuBO4NKMyGwbJR4DjbLUdr/Fb9TEXCgPXYFrP+leWAWXeEBMhB7pmcJnFweb4aa/pm+Pzerc35SfPKspg6+fV3XJsCo3AeGjae4CwXCIjQydPcTSQivNs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298286; c=relaxed/simple; bh=tkjolWLEFTX+OjQUDiavG2ySNkEp4jtu1RA/RK1P54M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PpkRKG1lwKaSnm+L4AKSHsU15ItM4nqd4KmzhNcOr5QSMbwuiPrJBgxJGPuxgtaoAssIxfMSWD0iNURf6IoUPW3WsQwIEz9Iu1TyZnQDcxUgMVEdTpfr5h2gtrHuNFLedyDXHBnisbHRp+ZXMApDXCewjgTR4LZE+3KYhhyKB+A= 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=cVXw6GRm; arc=none smtp.client-ip=209.85.208.50 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="cVXw6GRm" Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-61580eb7995so9165479a12.0 for ; Mon, 04 Aug 2025 02:04:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298282; x=1754903082; 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=acPLPksJ6hNGFtXGEUrlTi9y16bOXH39niwzv4irAiQ=; b=cVXw6GRm8CIVPqAwBt4RJ+5UM+x+AxW8KoZr1sgaNvMbDjyJwa6V2xDSKuxil8FTo0 XGZ9jifotqoX57oU9SiWUEkls2ck6EEvjgHb/1hsUmZp0fZiTgDdVHjW0ElkxKI9DH4Y 9aX6JAXxpamoZWif39O/K9qZP6ufQmdfm82W8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298282; x=1754903082; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=acPLPksJ6hNGFtXGEUrlTi9y16bOXH39niwzv4irAiQ=; b=lcehp4+r9cZBxeE4qx30kiNo87nkgbolKe4mMMxDMBugz6IXFh45XoXtrdsliCq3SS I/X34cdV8mLr11KAfP1FjIoRAy4Cmun26K3TGjJvN1dASEBkQFvDJjb/BTsAIlX7nC8a FzJ8gxfbcelXDD5EnHf6yCVvDRrurgcbwtxkYXY/BvfMi8/3TJR+v3kROTz8N2bRLk7w 8FV8u1yMqr6/ZWvYFZlbTA8z8LGKrIvUqHUnz2m7YikJaRU5hChHmLU6UAK6ZY1r3keA LX4o3Rkx0aZ26bOt9+3PxXMj/8ntPghhDZY+HWpigMYO0J2dqJ+49DH9ahZda+DFChcR 6tzA== X-Forwarded-Encrypted: i=1; AJvYcCUl8Wv/9g/t2mnHAtJTN8yMnFqytw/ymGZqziMWJrc1Ok2OjeWH/pqZEd9eiHK+ajLBqmofWwlfvjICjgk=@vger.kernel.org X-Gm-Message-State: AOJu0YxxeQUrgzd1cvRd0r3r73RjBgKZcrLLsw4BHT4oEWGlRxB4/HXk 9UzUTjuZPSFP8p90LXE6WNYSO3EwbYjVBAS3uWUzvc9neyV0Gtw4lo27ZexejgdvWcYau449grn O7FM= X-Gm-Gg: ASbGncuR45hQ4bIFizutNONNXtqFP93M31nJ3UL0SeaOHjxF2oL5jIYIjPlhAZWEG/H Ing2diG164NysKFWOuWKwmpT7xu4YHUV0cupCj2togcTpi462MlWptu1iUO2zuzgmuTzQvqXcNZ FvJHMm+aqaC7Xz6hQ0Gp0Pak2VTCu80/kuR+HtTFv+V4c3OfcYbDomnOeXcBfmh4Xd/wMAtD+oY rfkS/6hxfl5cmuUXXlnq5i2tR/Ia67tL5w/Bbcg7/ZRYhZjwp/jQsxpLLmkw0qPt39HH+MiL1pH dvgrrzcpb5W7lPIDzttKYHm2F7aXZJDx9+S0Ue9qWh3jdjQuButo4bljBtmYrz5fRM3V0MgrKtr bZggMwT9IDqkeIGJYjQnP5uH9oFPYVPwwDtysl6+setgqwEaeo65pFX/xfEgJheLKLfYpyH8BlE 8L/h2rt7JQBqJ6rJ8= X-Google-Smtp-Source: AGHT+IGBrFrtKrp8IAVwQW4QJ7evIiRgZVahLOGnZ/LOmxojYWUqcdIWg8WDD4PI3iYTDOroj7yh0g== X-Received: by 2002:a05:6402:381b:b0:615:9247:e2fa with SMTP id 4fb4d7f45d1cf-615ae1c4112mr14025240a12.8.1754298281722; Mon, 04 Aug 2025 02:04:41 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:41 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 08/10] platform/chrome: cros_ec_typec: Propagate altmode entry result Date: Mon, 4 Aug 2025 09:03:37 +0000 Message-ID: <20250804090340.3062182-9-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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" In the `cros_typec_configure_mux` function, which concludes the DP/TBT alternate mode entry, the error code should be reported back to the Type-C mode selection logic. This ensures a detailed result is conveyed to user space. To inform partner drivers about the result, the VDM mechanism is used: DP_CMD_STATUS_UPDATE for DP altmode and TBT_CMD_STATUS_UPDATE for TBT altmode. Signed-off-by: Andrei Kuchynski --- drivers/platform/chrome/cros_ec_typec.c | 9 ++++++ drivers/platform/chrome/cros_typec_altmode.c | 32 ++++++++++++++++++-- drivers/platform/chrome/cros_typec_altmode.h | 6 ++++ include/linux/usb/typec_dp.h | 2 ++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chr= ome/cros_ec_typec.c index 99f549263c37..73aa25433a50 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -693,6 +693,7 @@ static int cros_typec_enable_dp(struct cros_typec_data = *typec, if (!ret) ret =3D typec_mux_set(port->mux, &port->state); =20 + dp_data.error =3D 0; if (!ret) ret =3D cros_typec_displayport_status_update(port->state.alt, port->state.data); @@ -782,8 +783,16 @@ static int cros_typec_configure_mux(struct cros_typec_= data *typec, int port_num, ret =3D cros_typec_enable_usb4(typec, port_num, pd_ctrl); } else if (port->mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) { ret =3D cros_typec_enable_tbt(typec, port_num, pd_ctrl); + cros_typec_tbt_status_update( + port->port_altmode[CROS_EC_ALTMODE_TBT], ret); } else if (port->mux_flags & USB_PD_MUX_DP_ENABLED) { ret =3D cros_typec_enable_dp(typec, port_num, pd_ctrl); + if (ret) { + struct typec_displayport_data dp_data =3D {.error =3D ret}; + + cros_typec_displayport_status_update( + port->port_altmode[CROS_EC_ALTMODE_DP], &dp_data); + } } 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) { diff --git a/drivers/platform/chrome/cros_typec_altmode.c b/drivers/platfor= m/chrome/cros_typec_altmode.c index 557340b53af0..7ee295cf0c02 100644 --- a/drivers/platform/chrome/cros_typec_altmode.c +++ b/drivers/platform/chrome/cros_typec_altmode.c @@ -28,6 +28,7 @@ struct cros_typec_altmode_data { =20 u16 sid; u8 mode; + int error; }; =20 struct cros_typec_dp_data { @@ -295,9 +296,16 @@ int cros_typec_displayport_status_update(struct typec_= altmode *altmode, =20 dp_data->data =3D *data; dp_data->pending_status_update =3D false; - adata->header |=3D VDO_CMDT(CMDT_RSP_ACK); - adata->vdo_data =3D &dp_data->data.status; - adata->vdo_size =3D 2; + if (data->error) { + adata->header |=3D VDO_CMDT(CMDT_RSP_NAK); + adata->error =3D dp_data->data.error; + adata->vdo_data =3D &adata->error; + adata->vdo_size =3D 1; + } else { + adata->header |=3D VDO_CMDT(CMDT_RSP_ACK); + adata->vdo_data =3D &dp_data->data.status; + adata->vdo_size =3D 2; + } schedule_work(&adata->work); =20 mutex_unlock(&adata->lock); @@ -370,4 +378,22 @@ cros_typec_register_thunderbolt(struct cros_typec_port= *port, =20 return alt; } + +int cros_typec_tbt_status_update(struct typec_altmode *alt, int error) +{ + struct cros_typec_altmode_data *adata =3D typec_altmode_get_drvdata(alt); + + mutex_lock(&adata->lock); + + adata->header =3D VDO(adata->sid, 1, SVDM_VER_2_0, TBT_CMD_STATUS_UPDATE); + adata->header |=3D VDO_CMDT(error ? CMDT_RSP_NAK : CMDT_RSP_ACK); + adata->error =3D error; + adata->vdo_data =3D &adata->error; + adata->vdo_size =3D 1; + schedule_work(&adata->work); + + mutex_unlock(&adata->lock); + + return 0; +} #endif diff --git a/drivers/platform/chrome/cros_typec_altmode.h b/drivers/platfor= m/chrome/cros_typec_altmode.h index 3f2aa95d065a..848a2b194b34 100644 --- a/drivers/platform/chrome/cros_typec_altmode.h +++ b/drivers/platform/chrome/cros_typec_altmode.h @@ -39,6 +39,7 @@ static inline int cros_typec_displayport_status_update(st= ruct typec_altmode *alt struct typec_altmode * cros_typec_register_thunderbolt(struct cros_typec_port *port, struct typec_altmode_desc *desc); +int cros_typec_tbt_status_update(struct typec_altmode *alt, int error); #else static inline struct typec_altmode * cros_typec_register_thunderbolt(struct cros_typec_port *port, @@ -46,6 +47,11 @@ cros_typec_register_thunderbolt(struct cros_typec_port *= port, { return typec_port_register_altmode(port->port, desc); } +static inline int cros_typec_tbt_status_update(struct typec_altmode *alt, + int error) +{ + return 0; +} #endif =20 #endif /* __CROS_TYPEC_ALTMODE_H__ */ diff --git a/include/linux/usb/typec_dp.h b/include/linux/usb/typec_dp.h index acb0ad03bdac..c9fa68cd1265 100644 --- a/include/linux/usb/typec_dp.h +++ b/include/linux/usb/typec_dp.h @@ -44,10 +44,12 @@ enum { * commands: Status Update and Configure. * * @status will show for example the status of the HPD signal. + * @error will contain the error code, if applicable. */ struct typec_displayport_data { u32 status; u32 conf; + int error; }; =20 enum { --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ed1-f43.google.com (mail-ed1-f43.google.com [209.85.208.43]) (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 3BC60253956 for ; Mon, 4 Aug 2025 09:04:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298287; cv=none; b=MWAq6VuPMig/pZK3HnNgZEzeRrOSKI/6ADqmcwaYQNkZi7Nugd/gb9b0x3xc3/hHgPGvfKAEip/9+SGtSnhY1pFm/tsiIKPgEjL3ZazAoP6jcMZXWrYbSIiCe9IuzlH+sxzrOU8VsJxnC79vkFaQxFq/lsB5b5xaDk/3TmO7XWo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298287; c=relaxed/simple; bh=VYWbWVA057Y0qPzEMkQr0mmrYKKhYX7GNZV3gzsbgLg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iHZEXfDYJZmV7r7hJDhwHZ8ajmwtM+MmItZoLT5L9OZ61BMZhq/zksXmsPU/V4+ZDbDzcyBi/r3UtejCx+M7laMzn7+d9mR6V1l5SxIaseamcTI/LOXRr5OUFu8YyK3HyQPesAHmTPGFhrS1j7JJ+P7JdIUJxj1U2/puvQQgtJ0= 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=FLGfp9lP; arc=none smtp.client-ip=209.85.208.43 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="FLGfp9lP" Received: by mail-ed1-f43.google.com with SMTP id 4fb4d7f45d1cf-61530559887so5301968a12.1 for ; Mon, 04 Aug 2025 02:04:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298284; x=1754903084; 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=6fCXGPTGTKW8fArN1je3Wq8jIm9fq53nnnBhW5Sy8xE=; b=FLGfp9lPS4bFipSLKlAX9qsUbEvWDk7NyOmrntSJ4t3MfVXdrrXEpLIk1l2xY4WqC+ iKx/j4WBiUY9SbD9Sq60SwclvSr2lwkRRnHP5WsF8N/blpsMjlgRXaq1LP0nRzMxlpbf GPuNG3G/58XD1tgNp362Jd8CkPFwmneqyuP7Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298284; x=1754903084; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6fCXGPTGTKW8fArN1je3Wq8jIm9fq53nnnBhW5Sy8xE=; b=MpYlqllEl97ywnJa6x+SqWDM+AKKPE+82wHn1o83RM77kQm/fp7gm57I1pH4JhTRQ1 J7shHVwdTQNXgVMoOIYVNJXdHCWH0UB8dQdVNigzSMd0zV6vM1SDh0fkaLWGrNCEAQ1Q 5xxBRfEthmHtDERKZBXOJJChM1hXFoU21uhxpq/dMu5ckU3uMEheOSdzOGRv8ZUKwkYz tvVM57jEtkzBumjTvDBOZgXE/oYO41EC+MUdQikt5ceakjRkoQSnmv5qheRTPkYt2+ql vcClGdhASEa+D6PgwRDK4/Vp009MjHUsQqOhWIBRUadkG+AC9cB+vuAdLTL0m6QgyXJ4 b32g== X-Forwarded-Encrypted: i=1; AJvYcCUeIPhUsHwjIfjOM2MMXRLLUzPF8VmFFojQkZ4XM32nRMJL7NnPE5slJ+QrDWwjkZ0tlYl5Jmh+a3Haq7Q=@vger.kernel.org X-Gm-Message-State: AOJu0YyewsTBdt4+VK9OTCJk6Extgqf+mR7dfsm77DuXEcsKIxPBhOtK uFxEufsz0ZjbYkxq5VtteO23lv0Ttj2VsqlmfvoLUv7MR/p5jqN7o2+QMdzdTUsZiA== X-Gm-Gg: ASbGnctt9ECa3tP1tLFSIkCIqnCoREpWDFItc5KXB5g3cxdslaBJPVIRMCka9OJAEeP MfAr6xa4PF/fTtKWxYAjzuxtSfnAcoSrP8gQ6xTtG6pCckOJ5T8ulCNcJoe+52lO0Llq98lnLb6 yzSywBha/AQVj5nApdR3z2gzOzSTp+lwsY+b5+hBD6Z1mdaZOMcMSW5303yWSMdwzAHS9BPZ0E1 UYcUkXx3rctzz/lmX1OcbqsmnwtlAjMCzKaEoy19Y1ckP6XAAqgjN91kN3scuC7P9F8nx2EQAyW V2xS9snrjNy3rfo5e3Pau5KmsgTfex/JosttdAbc7qRsd/pvbMvDaFtyrjEgqMInieJxkSKk98W xMtPuLeJOX7Hc+geYZrXAldtmejgo3wu9zxG5hVOsAkHeBue9Xj6WoDF1w8dr4wIYNv+GUtSnKJ hv0UONPb0bPXnrwxk= X-Google-Smtp-Source: AGHT+IEahG0mX+I5PDgV3Sb0a4d6qhy92gyT+o8P9htq7Mc1BKgfiFsyNZ/upIlcaxMDJ6sg67zRFw== X-Received: by 2002:a17:907:9690:b0:ae0:66e8:9ddb with SMTP id a640c23a62f3a-af94000dc4bmr1075715866b.19.1754298284566; Mon, 04 Aug 2025 02:04:44 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:43 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 09/10] platform/chrome: cros_ec_typec: Report USB4 entry status via callback Date: Mon, 4 Aug 2025 09:03:38 +0000 Message-ID: <20250804090340.3062182-10-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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 Type-C mode selection logic requires feedback on the result of USB4 mode entry attempt. Call the `typec_mode_selection_usb4_complete()` callback to provide this final success or failure status. Signed-off-by: Andrei Kuchynski --- drivers/platform/chrome/cros_ec_typec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chr= ome/cros_ec_typec.c index 73aa25433a50..5a3d393c26ee 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -781,6 +781,7 @@ static int cros_typec_configure_mux(struct cros_typec_d= ata *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); + typec_mode_selection_usb4_complete(port->partner, ret); } else if (port->mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) { ret =3D cros_typec_enable_tbt(typec, port_num, pd_ctrl); cros_typec_tbt_status_update( --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Feb 8 20:20:21 2026 Received: from mail-ed1-f51.google.com (mail-ed1-f51.google.com [209.85.208.51]) (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 1933D2550A3 for ; Mon, 4 Aug 2025 09:04:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298290; cv=none; b=cQKrgFVN5f/uZ5bEf2812xhZPrVmg8s5PSvPD2LYWVysOtswE4nJ2cAbLmFviIh1/5vc4a1IzSmZTeiFduoo8Ykvv1rghjLHv+erOtPLIgLTsrs5/Yb+psh6pe2g8Tl1Y5Ex0+1jYaR1KtcVWnF87vHPDzFjbL9OTnPDi5hEd1U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754298290; c=relaxed/simple; bh=3x19bC4TEkjCbZhfuYqU5c/VjurC/2Z6kwyVqMzBqdE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=j9AGYdyFchSrlokLdYMCLsp4hMf4o+864D3Vm2kWKkASr78rTq5sd+4oSmQrhfYbcrhw+8SyRlxDdXujTrZ5qGnFsKBmQjhW/mAInw+8tuuTxggUoXzc0e1oQVRx7fJp87/Am73w5PUKr1jm1P9sVxhOrjmFKPz0XGnX3hzJRwI= 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=Xg4tAtW7; arc=none smtp.client-ip=209.85.208.51 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="Xg4tAtW7" Received: by mail-ed1-f51.google.com with SMTP id 4fb4d7f45d1cf-605b9488c28so7303920a12.2 for ; Mon, 04 Aug 2025 02:04:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1754298287; x=1754903087; 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=vnQpTwABThBxdUskT3LdV6JNdqJ4VQSfDvVtzabNNUU=; b=Xg4tAtW7xI5NriBCXr/EdjYAbEtUfVMZ2+Qf9K+XZt8Iin1MVlmenKAaFiPkbbczgg 5nMpBLjUSxSvkgJF1tWRiwhQ4yIWmVG4sb5wU7nCWcRNeffEH8NQL4AK3RhVg73PdOXD AZO778+w8MLZJ4+3SPDV2uLLWECf3YYeVOLK0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754298287; x=1754903087; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vnQpTwABThBxdUskT3LdV6JNdqJ4VQSfDvVtzabNNUU=; b=w2+FoExLI5RpslfHm0K63VrBWejdRRXTkTDkm8EPtMfuOzSHOnjWEn4FwvFJ+GK+Ir eN6+RP6CX7PNAfCfVzSDglP9Q6q9pZIcoaLU4Rb/n/i5OEYPc1xJbqYDloFnnSyNjVTv cH+ro5lEHMPEpPWeTVeIaiIRR2G1K/A22rK8cUOGZ1SSGGpdZQ/fnW8rprBy6C/N+OwJ X7jxOr5hubq36+Mviu1Pr4wPf+FD3etlQD03sJTuQrA6wskEDTSHk5FclGQMeXqT11dQ jxD2tNxNpQbIynRSQXLy9/viCBca9JhmTbMpFnZ3i60ThfssF3jRoVVeMWY9L6cUhZIX VywA== X-Forwarded-Encrypted: i=1; AJvYcCVrw0KB+w5itcSbRjsRYQMg1/WLjzdJ1jpibF0qGYUOvcsadLmytzpwLgcMmdrzACvImCuHshk/5s4IggM=@vger.kernel.org X-Gm-Message-State: AOJu0YzSb+KmMKR/yq+Dkcglbqzqi1W006d1+l6o/z9J5/A7rPXoanBu ONLe/WjrHSE0ymp+/HaqxChj4EMsm3dAuUxkp8i1Y1UC6XGkF8exixGAM/42DWPz9w== X-Gm-Gg: ASbGncuy6O6agUb0PQYWItvlcZTvLQBrebD1k+DBAhSUbYJ2bag2gZZF9npNJAZ36D3 9JyeT1vvaO7rgyclHjq6eZysJvrh/RDuKWrFWPuOe+nVGXl/2UN9I+dP4197iRC3caZVO8S1olg SlH06g+ujWCg8aKpOYzjaVNpfgbEHnMK4TWXHzb9c4PLCoptolmlH9rEduJdizxGxdBwAvvt3AM B8VCpWPoaB8c+N9AoFM4deKjbgmzlTA8RuqjkUCUI9errp8NEPCY9aL5ppvcIikvq3WCn7BSs1H FiROZE7kRKnypEqMaM+BAanUO/IkJRco+KVN5H6XLCIfFjLlWOiGtz0SvjMxUZVCurvGlzWhH4q YGCnuYAaf1KYv2YnnSt+2KT0/Gc9dVyArKkvDLJupXyFwFGXie+vvPpzKsVANi7ZoW75osv2hro fqP2Xd1aS5WqLJTltBLs4J9sOOVQ== X-Google-Smtp-Source: AGHT+IHrHxXdeaPG9B8IlHKEHEVk1KBLXqnoXcB8NheI8LMoc58AFyO+W+Fv2Eq44g8cl/NgunqeAg== X-Received: by 2002:a05:6402:3788:b0:615:38e6:b739 with SMTP id 4fb4d7f45d1cf-615e6ed456fmr7575534a12.10.1754298287331; Mon, 04 Aug 2025 02:04:47 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (150.230.32.34.bc.googleusercontent.com. [34.32.230.150]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-615a8fe7995sm6412790a12.36.2025.08.04.02.04.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Aug 2025 02:04:46 -0700 (PDT) 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" , Venkat Jayaraman , linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v3 10/10] platform/chrome: cros_ec_typec: Add default_usb_mode_set support Date: Mon, 4 Aug 2025 09:03:39 +0000 Message-ID: <20250804090340.3062182-11-akuchynski@chromium.org> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog In-Reply-To: <20250804090340.3062182-1-akuchynski@chromium.org> References: <20250804090340.3062182-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 `cros_ec_typec` driver currently doesn't directly consume a default USB mode value. This commit adds the `default_usb_mode_set` function, enabling the `usb_capability` sysfs attribute to be writable. This functionality allows users to dynamically activate or deactivate USB4 mode on a given port. Signed-off-by: Andrei Kuchynski --- drivers/platform/chrome/cros_ec_typec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chr= ome/cros_ec_typec.c index 5a3d393c26ee..9bfe78e315fc 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -44,6 +44,11 @@ static void cros_typec_role_switch_quirk(struct fwnode_h= andle *fwnode) #endif } =20 +static int cros_typec_default_usb_mode_set(struct typec_port *port, enum u= sb_mode mode) +{ + return 0; +} + static int cros_typec_enter_usb_mode(struct typec_port *tc_port, enum usb_= mode mode) { struct cros_typec_port *port =3D typec_get_drvdata(tc_port); @@ -140,6 +145,7 @@ static int cros_typec_pr_swap(struct typec_port *port, = enum typec_role role) } =20 static const struct typec_operations cros_typec_usb_mode_ops =3D { + .default_usb_mode_set =3D cros_typec_default_usb_mode_set, .enter_usb_mode =3D cros_typec_enter_usb_mode, .dr_set =3D cros_typec_dr_swap, .pr_set =3D cros_typec_pr_swap, --=20 2.50.1.565.gc32cd1483b-goog