From nobody Fri Apr 3 00:00:18 2026 Received: from mail-dy1-f174.google.com (mail-dy1-f174.google.com [74.125.82.174]) (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 7BE932343BE for ; Sun, 15 Feb 2026 06:13:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136026; cv=none; b=iMyUwzxFTZkWuC3xFJEgeQtkxafgHZ2JpJ3ps8jdAsR5dxnVhUpFxrSP7vrX+tX0/H6WmdSJk0RSIJu2gHkq5gqhVQ3KIq8ym8uWRQF0QDDaOjA2siSZaEgB23XcAhISiXILESngy9PESn7UjzMYI9LWFejHYe0havcOo0oCfY8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136026; c=relaxed/simple; bh=7TzMQusOog6JF0pcK98i5bR2p+94x7VAFTBLsStvemY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jw6iTDR9LDDO7fhnDZPS6RV4VQsQ+Hx+G0tv8fxP0f5H8hHCAFFe3ude62x0KhBw32OXl5JV1lDYT1PxPVIAbbbKF80tLJiDGuJI5tqVlmDC1efQIzw1itR2sXfgYXAIKGS/700fyCKu/Ed80Revm3LnGiEmHDxtvOBSgdNk/Rg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=l0uqnlAd; arc=none smtp.client-ip=74.125.82.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l0uqnlAd" Received: by mail-dy1-f174.google.com with SMTP id 5a478bee46e88-2ba68df3687so3893042eec.1 for ; Sat, 14 Feb 2026 22:13:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771136024; x=1771740824; 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=Cip+4LCLlCAb7SLYCPAq2l9B4U2w4m4LbqREr4Rxhfw=; b=l0uqnlAdfYFM4x6DDRbtO9S5GA/Oq/wSaJMyNWOEXdoTABAuanMNgVLxt8KP/y91id 5WoZYW3bwsI49S2IIs2lEPkfyzdkDQMhoq8NXAtuH+ZcGimIyKCGip+2Oc41HlIGmAQe ypeZEuTRFtkqQ8T3wmzMzrnbhrqUEGi1nmz1EhslRwobXdP1A551SgSab31PUoAmkcQA /1oSYdk34ffw3HV+1OrgDpGnosc/TxAHnvHbzYWenrhIbZ926qXcyKZg9Bh7QwTrpXcx jyUszDt8O6eTE+RR+3MMBNw2mYuZQw3okuv2tiT+M7xWcK6YoagU+tiKa2bvuBgBXGxF fYTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771136024; x=1771740824; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Cip+4LCLlCAb7SLYCPAq2l9B4U2w4m4LbqREr4Rxhfw=; b=e1vTaXoNSEBLjFSv9OzAS6BC54iPyKt073AOOzVjbMhGcs5J13+QybygTGRQrkdFRD PP+jL1OUUOEENLrtXRNKSwB8Hytfa70z+9hvD4f1yV4NCWwgSd0Xon4t2qun5OaFAlTG frbTqDjEAeJC31TjM6enH4R2F/elShVq5QM/8acScgOyhuc1vlJVW5XFPuHsJD3vVPXk xU4YvNOrk8oYCju0NC9346aciWzPP5lRvinivx1vZsis9wti3vfmUje1hf3ovIbRx8Ss SbuaKfpUQI0wXUsVTgRgyXVx1E5K9dTqSCNxsVJ0wA2uhaHo+mtJks0zG1fgpgAXk1Kp noWA== X-Forwarded-Encrypted: i=1; AJvYcCUZWbESGMoZyDL1sJAnxZVtNWxfBNDwwIqMgQYzbY3em0LBvHZ1AGKrglLGBIjcHlrl4T4jCQSPnXK8MAw=@vger.kernel.org X-Gm-Message-State: AOJu0YzJOdL0OI45wiOKKuRbLZAHQQQ5bxallGWT6p3THWATZ9CjbDTV vCB17DMtkb8sxREe4tF421g8yOTqA1EpusWhQPApzpUkzEuaptn+cxBB X-Gm-Gg: AZuq6aI4W6dxDdl/wE7/mdVRKJe8YFuqL4WycbsqfICGkdG9rrMk4zwB8aWDb2acq8u NHB1XeW4BDF1fCSOQTsUui5KZVzh+AX/FylpAtYfVCDqiciZS8nJvvKtcWURuIrs6L42m4gwxKW gM1riq45TnbJUhR5Z83shr/184KarxyaExwA7WfwCrTokP2d+sqzJgirszRZ9537xT7GVDuXehP 9clTulYyLayFLY0j88OoD5HNF6ZYMAiVQtOJoIEgcVvXeSrrfWY9wQv2QUrZEvjIbQNcvQ7v5Wa nH12E+lUCzZc7Fs5rg6VcGXSF7Bsb8GCxvCHATddBlniXRe3YBS7j+s8QQEOHXqdKokfLFhbnNI kR43Rb+F9vVF/3QIS3axBiS8LekCKDETK9cy4H6yLBJiXQS6aAhdQ/bBtZCztmsLvm+wOqBaKje k62pxU5BFyOCo1vylOau1COkWYFYTmf2OEq7v5unsTWAXCEcL8Z6XfQlnDJ0atEQVphlvS08D8e T8= X-Received: by 2002:a05:7301:688c:b0:2ae:5d3b:e1ba with SMTP id 5a478bee46e88-2bac9795c65mr1765212eec.23.1771136023599; Sat, 14 Feb 2026 22:13:43 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2bacb577bcasm4759245eec.12.2026.02.14.22.13.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 14 Feb 2026 22:13:43 -0800 (PST) From: "Derek J. Clark" To: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Hans de Goede Cc: Mark Pearson , Armin Wolf , Jonathan Corbet , Rong Zhang , Kurt Borja , "Derek J . Clark" , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/6] platform/x86: lenovo-wmi-other: Add LWMI_ATTR_ID Macro Date: Sun, 15 Feb 2026 06:12:54 +0000 Message-ID: <20260215061339.2842486-2-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260215061339.2842486-1-derekjohn.clark@gmail.com> References: <20260215061339.2842486-1-derekjohn.clark@gmail.com> 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" Adds LWMI_ATTR_ID macro. In the same vein as LWMI_ATTR_ID_FAN_RPM, but as a generic, to de-duplicate attribute_id assignment biolerplate. Signed-off-by: Derek J. Clark Reviewed-by: Mark Pearson --- drivers/platform/x86/lenovo/wmi-capdata.h | 6 ++++ drivers/platform/x86/lenovo/wmi-gamezone.h | 1 + drivers/platform/x86/lenovo/wmi-other.c | 36 ++++++---------------- 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x= 86/lenovo/wmi-capdata.h index 8c1df3efcc553..27202e2dc8a59 100644 --- a/drivers/platform/x86/lenovo/wmi-capdata.h +++ b/drivers/platform/x86/lenovo/wmi-capdata.h @@ -17,6 +17,12 @@ #define LWMI_ATTR_MODE_ID_MASK GENMASK(15, 8) #define LWMI_ATTR_TYPE_ID_MASK GENMASK(7, 0) =20 +#define LWMI_ATTR_ID(dev, feat, mode, type) \ + (FIELD_PREP(LWMI_ATTR_DEV_ID_MASK, dev) | \ + FIELD_PREP(LWMI_ATTR_FEAT_ID_MASK, feat) | \ + FIELD_PREP(LWMI_ATTR_MODE_ID_MASK, mode) | \ + FIELD_PREP(LWMI_ATTR_TYPE_ID_MASK, type)) + #define LWMI_DEVICE_ID_FAN 0x04 =20 struct component_match; diff --git a/drivers/platform/x86/lenovo/wmi-gamezone.h b/drivers/platform/= x86/lenovo/wmi-gamezone.h index 6b163a5eeb959..ddb919cf6c36d 100644 --- a/drivers/platform/x86/lenovo/wmi-gamezone.h +++ b/drivers/platform/x86/lenovo/wmi-gamezone.h @@ -10,6 +10,7 @@ enum gamezone_events_type { }; =20 enum thermal_mode { + LWMI_GZ_THERMAL_MODE_NONE =3D 0x00, LWMI_GZ_THERMAL_MODE_QUIET =3D 0x01, LWMI_GZ_THERMAL_MODE_BALANCED =3D 0x02, LWMI_GZ_THERMAL_MODE_PERFORMANCE =3D 0x03, diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index 6040f45aa2b0d..95886df39c8d2 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -71,10 +71,9 @@ #define LWMI_FAN_NR 4 #define LWMI_FAN_ID(x) ((x) + LWMI_FAN_ID_BASE) =20 -#define LWMI_ATTR_ID_FAN_RPM(x) \ - (FIELD_PREP(LWMI_ATTR_DEV_ID_MASK, LWMI_DEVICE_ID_FAN) | \ - FIELD_PREP(LWMI_ATTR_FEAT_ID_MASK, LWMI_FEATURE_ID_FAN_RPM) | \ - FIELD_PREP(LWMI_ATTR_TYPE_ID_MASK, LWMI_FAN_ID(x))) +#define LWMI_ATTR_ID_FAN_RPM(x) \ + LWMI_ATTR_ID(LWMI_DEVICE_ID_FAN, LWMI_FEATURE_ID_FAN_RPM, \ + LWMI_GZ_THERMAL_MODE_NONE, LWMI_FAN_ID(x)) =20 #define LWMI_FAN_DIV 100 =20 @@ -716,12 +715,8 @@ static ssize_t attr_capdata01_show(struct kobject *kob= j, u32 attribute_id; int value, ret; =20 - attribute_id =3D - FIELD_PREP(LWMI_ATTR_DEV_ID_MASK, tunable_attr->device_id) | - FIELD_PREP(LWMI_ATTR_FEAT_ID_MASK, tunable_attr->feature_id) | - FIELD_PREP(LWMI_ATTR_MODE_ID_MASK, - LWMI_GZ_THERMAL_MODE_CUSTOM) | - FIELD_PREP(LWMI_ATTR_TYPE_ID_MASK, tunable_attr->type_id); + attribute_id =3D LWMI_ATTR_ID(tunable_attr->device_id, tunable_attr->feat= ure_id, + LWMI_GZ_THERMAL_MODE_CUSTOM, tunable_attr->type_id); =20 ret =3D lwmi_cd01_get_data(priv->cd01_list, attribute_id, &capdata); if (ret) @@ -776,7 +771,6 @@ static ssize_t attr_current_value_store(struct kobject = *kobj, struct wmi_method_args_32 args; struct capdata01 capdata; enum thermal_mode mode; - u32 attribute_id; u32 value; int ret; =20 @@ -787,13 +781,10 @@ static ssize_t attr_current_value_store(struct kobjec= t *kobj, if (mode !=3D LWMI_GZ_THERMAL_MODE_CUSTOM) return -EBUSY; =20 - attribute_id =3D - FIELD_PREP(LWMI_ATTR_DEV_ID_MASK, tunable_attr->device_id) | - FIELD_PREP(LWMI_ATTR_FEAT_ID_MASK, tunable_attr->feature_id) | - FIELD_PREP(LWMI_ATTR_MODE_ID_MASK, mode) | - FIELD_PREP(LWMI_ATTR_TYPE_ID_MASK, tunable_attr->type_id); + args.arg0 =3D LWMI_ATTR_ID(tunable_attr->device_id, tunable_attr->feature= _id, + mode, tunable_attr->type_id); =20 - ret =3D lwmi_cd01_get_data(priv->cd01_list, attribute_id, &capdata); + ret =3D lwmi_cd01_get_data(priv->cd01_list, args.arg0, &capdata); if (ret) return ret; =20 @@ -804,7 +795,6 @@ static ssize_t attr_current_value_store(struct kobject = *kobj, if (value < capdata.min_value || value > capdata.max_value) return -EINVAL; =20 - args.arg0 =3D attribute_id; args.arg1 =3D value; =20 ret =3D lwmi_dev_evaluate_int(priv->wdev, 0x0, LWMI_FEATURE_VALUE_SET, @@ -838,7 +828,6 @@ static ssize_t attr_current_value_show(struct kobject *= kobj, struct lwmi_om_priv *priv =3D dev_get_drvdata(tunable_attr->dev); struct wmi_method_args_32 args; enum thermal_mode mode; - u32 attribute_id; int retval; int ret; =20 @@ -846,13 +835,8 @@ static ssize_t attr_current_value_show(struct kobject = *kobj, if (ret) return ret; =20 - attribute_id =3D - FIELD_PREP(LWMI_ATTR_DEV_ID_MASK, tunable_attr->device_id) | - FIELD_PREP(LWMI_ATTR_FEAT_ID_MASK, tunable_attr->feature_id) | - FIELD_PREP(LWMI_ATTR_MODE_ID_MASK, mode) | - FIELD_PREP(LWMI_ATTR_TYPE_ID_MASK, tunable_attr->type_id); - - args.arg0 =3D attribute_id; + args.arg0 =3D LWMI_ATTR_ID(tunable_attr->device_id, tunable_attr->feature= _id, + mode, tunable_attr->type_id); =20 ret =3D lwmi_dev_evaluate_int(priv->wdev, 0x0, LWMI_FEATURE_VALUE_GET, (unsigned char *)&args, sizeof(args), base-commit: 5a5203a45b063a594e89a2aeaf9e4923893a5b4c --=20 2.52.0 From nobody Fri Apr 3 00:00:18 2026 Received: from mail-dy1-f179.google.com (mail-dy1-f179.google.com [74.125.82.179]) (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 4E45C24A054 for ; Sun, 15 Feb 2026 06:13:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136026; cv=none; b=Z9PNjihmRVa721+axsD1NfY5yhk8ucDNWmoRA5lJJK6J/bUFXCfG06+LmhyXZvx2yt/NcgRgXKeixKCi4UnMysGtr4kZdSP56Ym1pJ/NkeurUVZa3I1O+brFPYQrwr1hiayNWiI0tyKOKyVBXNXdqIzh4OqluI5XtsPYQof/xX0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136026; c=relaxed/simple; bh=0WY/6++ifxZzESmD3bALeKnLCRCtyf7YwTde+fN6yx4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JbQOMlnekir1cHzAeyjcyYBlG22cIHvkppSjg8AmGxsMvgn5BJWn4qZmwGxM6tzfUoGn2gB47A15xzozlHh5kOEmHrD2SEZtA5OTE7lCNwWRG7bWjBebiptIvU756CNKUfbK0XDgB05cOVZVA5Q6V5Fm7/hGzVWNl0EPP/nfnZY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KRODG7JN; arc=none smtp.client-ip=74.125.82.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KRODG7JN" Received: by mail-dy1-f179.google.com with SMTP id 5a478bee46e88-2b82c605dbdso4746880eec.0 for ; Sat, 14 Feb 2026 22:13:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771136024; x=1771740824; 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=D9xOxtR3CWKKMh61qfUolY9qoF61BVM7C9Huh+ukUgc=; b=KRODG7JNubpNsOt66msFei1r+88YcKjWND8AW3rPpdBXh/dXjznsSMVbqJL7F6PSxN Sz7gyRbPaGH5Lz9PhzlcRV+xu5rdkH6qNtLGPt+XcS0sbbzNxNyhWmHAgGjG7dEjboh/ nRLWMrqSV6NdPWmblUYrEup0CfUfUW4yjJUR9aeUvCE4OvoRXeMcdDw7VocKM/Syk8fL iFaZbWWsL0MbY7frdUydmHlONCCaj9dHlvOmYUoGL/wmTfRGqjRpshXWFfXgD2KLNIlS 5E/W2jPwcCFFABrujMuCGXrcRBbqx+g2gJBN3FTEwS85lpr1T0IqcE8cG+sck3pvyBlT NKMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771136024; x=1771740824; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=D9xOxtR3CWKKMh61qfUolY9qoF61BVM7C9Huh+ukUgc=; b=JpKvKF7Hp0hZr08WtAfxziDK9kt0hDcuppg1LQY+DomhVQwLZfJiwKOL1cJXQ3QNqS YUL92YZf0L5MyK7hWh0egZvURZSMTy+wtl41sII8aZbPaAoKkFPxEqnqUVGcrCDWx0/a vFGJ0CGqkA8fD7UxYTD1kzRyJ4Msz2ZcXi/KJ+667t+n3lFuRJOYvH3si+rQPt688pUV JSQRFGNFEP1wWL+mWGHyJB1cM0e8ZAjZgYAr4zm4YPB8bIxVg7G2QNU82FFr7kihaVgb sGG9PC26AV90XP6t4dhE85sgbDIBNDLakc+VX7TJnxEXjienpXdl/OQ6CGDEnR1kKPQu lHWw== X-Forwarded-Encrypted: i=1; AJvYcCXH0s8WHP9pDuLNaFeFO8qB5OOkl6rxWRQZLwpxltSFakm3AJPhxylrEDPP4CzXBY1TiaSBxjkPzOZsa1g=@vger.kernel.org X-Gm-Message-State: AOJu0YwLJjQnkkGb0h0ilXQ7HUfqJUrvnOylwjjRy95kY3GcwVBFM8vg DbNY3mou8Hw0J1U8u5XD1utoeAU6hsCGKB6M3M5dKCH6x9n9lWIBBMhz X-Gm-Gg: AZuq6aLZnVrNXNgNa3KKLk14HQWnKSiYmRokHjtR7MpTjRz4xwOEAjdSHS8CID4VssH /icE0LO6RA9hxqeRNCPzza52dRaCAiE8VnSP3kcvBqPbzTc1siw92Im0WwSJ7rLPLsDc1Xl9A1X d2gsRXE4bh8TKk9AZNiuqT691+d8QVp68RSxvYqy1otRu0PGlOvNSCcFqG0dfWoKb/Ei7fyCqqE rkwTsIqx1Snaln6XCOnPBaYryrmYdyu38SKyJ9oQHNWj74mjP5i+a1yxwIz4Kv0Hu6yJsx3uj0B 2CtIaTIQm49nuiXyP1NgakC819qVdGjUv5Amap4jD+lHoFCUpKUxSuSrTvrxhwGlfB81HIQvLJk OnlDBF1Z0gfZIOGs0Ioo35Z/lnP2Zq+VumxAoUWE7D9iUHVLYqL1krs/12Rojt1KdHpCjWV0S+w W00Tl9eBusQC9b4syxnrCtGAppvOuYGKLTM90ZFd528mWKEzWd4e+MGpEUHpfDvwF+8YndpI/bH mg= X-Received: by 2002:a05:7300:fe0a:b0:2ba:72b1:40c7 with SMTP id 5a478bee46e88-2babc3b6ae0mr2900521eec.4.1771136024221; Sat, 14 Feb 2026 22:13:44 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2bacb577bcasm4759245eec.12.2026.02.14.22.13.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 14 Feb 2026 22:13:43 -0800 (PST) From: "Derek J. Clark" To: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Hans de Goede Cc: Mark Pearson , Armin Wolf , Jonathan Corbet , Rong Zhang , Kurt Borja , "Derek J . Clark" , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/6] platform/x86: lenovo-wmi-other: Limit adding attributes to supported devices Date: Sun, 15 Feb 2026 06:12:55 +0000 Message-ID: <20260215061339.2842486-3-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260215061339.2842486-1-derekjohn.clark@gmail.com> References: <20260215061339.2842486-1-derekjohn.clark@gmail.com> 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" Adds lwmi_is_attr_01_supported, and only creates the attribute subfolder if the attribute is supported by the hardware. Due to some poorly implemented BIOS, this is a multi-step sequence of events. This is because: - Some BIOS support getting the capability data from custom mode (0xff), while others only support it in no-mode (0x00). - Similarly, some BIOS support get/set for the current value from custom mode (0xff), while others only support it in no-mode (0x00). - Some BIOS report capability data for a method that is not fully implemented. - Some BIOS have methods fully implemented, but no complimentary capability data. To ensure we only expose fully implemented methods with corresponding capability data, we check each outcome before reporting that an attribute can be supported. Checking for lwmi_is_attr_01_supported during remove is not done to ensure that we don't attempt to call cd01 or send WMI events if one of the interfaces being removed was the cause of the driver unloading. While adding members to tunable_attr_01, remove unused capdata pointer and limit size of all ID's to the appropriate size. Reported-by: Kurt Borja Closes: https://lore.kernel.org/platform-driver-x86/DG60P3SHXR8H.3NSEHMZ6J7= XRC@gmail.com/ Signed-off-by: Derek J. Clark Reviewed-by: Mark Pearson --- drivers/platform/x86/lenovo/wmi-other.c | 117 +++++++++++++++++++++--- 1 file changed, 102 insertions(+), 15 deletions(-) diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index 95886df39c8d2..f3f12303e3798 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -545,11 +545,12 @@ static void lwmi_om_fan_info_collect_cd_fan(struct de= vice *dev, struct cd_list * /* =3D=3D=3D=3D=3D=3D=3D=3D fw_attributes (component: lenovo-wmi-capdata 0= 1) =3D=3D=3D=3D=3D=3D=3D=3D */ =20 struct tunable_attr_01 { - struct capdata01 *capdata; struct device *dev; - u32 feature_id; - u32 device_id; - u32 type_id; + u8 feature_id; + u8 device_id; + u8 type_id; + u8 cd_mode_id; /* mode arg for searching capdata */ + u8 cv_mode_id; /* mode arg for set/get current_value */ }; =20 static struct tunable_attr_01 ppt_pl1_spl =3D { @@ -716,7 +717,7 @@ static ssize_t attr_capdata01_show(struct kobject *kobj, int value, ret; =20 attribute_id =3D LWMI_ATTR_ID(tunable_attr->device_id, tunable_attr->feat= ure_id, - LWMI_GZ_THERMAL_MODE_CUSTOM, tunable_attr->type_id); + tunable_attr->cd_mode_id, tunable_attr->type_id); =20 ret =3D lwmi_cd01_get_data(priv->cd01_list, attribute_id, &capdata); if (ret) @@ -782,7 +783,7 @@ static ssize_t attr_current_value_store(struct kobject = *kobj, return -EBUSY; =20 args.arg0 =3D LWMI_ATTR_ID(tunable_attr->device_id, tunable_attr->feature= _id, - mode, tunable_attr->type_id); + tunable_attr->cd_mode_id, tunable_attr->type_id); =20 ret =3D lwmi_cd01_get_data(priv->cd01_list, args.arg0, &capdata); if (ret) @@ -795,6 +796,8 @@ static ssize_t attr_current_value_store(struct kobject = *kobj, if (value < capdata.min_value || value > capdata.max_value) return -EINVAL; =20 + args.arg0 =3D LWMI_ATTR_ID(tunable_attr->device_id, tunable_attr->feature= _id, + tunable_attr->cv_mode_id, tunable_attr->type_id); args.arg1 =3D value; =20 ret =3D lwmi_dev_evaluate_int(priv->wdev, 0x0, LWMI_FEATURE_VALUE_SET, @@ -828,13 +831,16 @@ static ssize_t attr_current_value_show(struct kobject= *kobj, struct lwmi_om_priv *priv =3D dev_get_drvdata(tunable_attr->dev); struct wmi_method_args_32 args; enum thermal_mode mode; - int retval; - int ret; + int retval, ret; =20 ret =3D lwmi_om_notifier_call(&mode); if (ret) return ret; =20 + /* If "no-mode" is the supported mode, ensure we never send current mode = */ + if (tunable_attr->cv_mode_id =3D=3D LWMI_GZ_THERMAL_MODE_NONE) + mode =3D tunable_attr->cv_mode_id; + args.arg0 =3D LWMI_ATTR_ID(tunable_attr->device_id, tunable_attr->feature= _id, mode, tunable_attr->type_id); =20 @@ -847,6 +853,85 @@ static ssize_t attr_current_value_show(struct kobject = *kobj, return sysfs_emit(buf, "%d\n", retval); } =20 +/** + * lwmi_attr_01_is_supported() - Determine if the given attribute is suppo= rted. + * @tunable_attr: The attribute to verify. + * + * First check if the attribute has a corresponding capdata01 table in the= cd01 + * module under the "custom" mode (0xff). If that is not present then chec= k if + * there is a corresponding "no-mode" (0x00) entry. If either of those pas= ses, + * check capdata->supported for values > 0. If capdata is available, attem= pt to + * determine the set/get mode for the current value property using a simil= ar + * pattern. If the value returned by either custom or no-mode is 0, or we = get + * an error, we assume that mode is not supported. If any of the above che= cks + * fail then the attribute is not fully supported. + * + * The probed cd_mode_id/cv_mode_id are stored on the tunable_attr for lat= er + * reference. + * + * Return: Support level, or an error code. + */ +static int lwmi_attr_01_is_supported(struct tunable_attr_01 *tunable_attr) +{ + struct lwmi_om_priv *priv =3D dev_get_drvdata(tunable_attr->dev); + u8 mode =3D LWMI_GZ_THERMAL_MODE_CUSTOM; + struct wmi_method_args_32 args; + struct capdata01 capdata; + int retval, ret; + + /* Determine tunable_attr->cd_mode_id */ +no_mode_fallback_1: + args.arg0 =3D LWMI_ATTR_ID(tunable_attr->device_id, tunable_attr->feature= _id, + mode, tunable_attr->type_id); + + ret =3D lwmi_cd01_get_data(priv->cd01_list, args.arg0, &capdata); + if (ret && mode) { + dev_dbg(tunable_attr->dev, "Attribute id %x not supported\n", args.arg0); + mode =3D LWMI_GZ_THERMAL_MODE_NONE; + goto no_mode_fallback_1; + } + if (ret) + goto not_supported; + if (!capdata.supported) { + ret =3D -EOPNOTSUPP; + goto not_supported; + } + + tunable_attr->cd_mode_id =3D mode; + + /* Determine tunable_attr->cv_mode_id */ + mode =3D LWMI_GZ_THERMAL_MODE_CUSTOM; +no_mode_fallback_2: + args.arg0 =3D LWMI_ATTR_ID(tunable_attr->device_id, tunable_attr->feature= _id, + mode, tunable_attr->type_id); + + ret =3D lwmi_dev_evaluate_int(priv->wdev, 0x0, LWMI_FEATURE_VALUE_GET, + (unsigned char *)&args, sizeof(args), + &retval); + if ((ret && mode) || (!retval && mode)) { + dev_dbg(tunable_attr->dev, "Attribute id %x not supported\n", args.arg0); + mode =3D LWMI_GZ_THERMAL_MODE_NONE; + goto no_mode_fallback_2; + } + if (ret) + goto not_supported; + if (retval =3D=3D 0) { + ret =3D -EOPNOTSUPP; + goto not_supported; + } + + tunable_attr->cv_mode_id =3D mode; + dev_dbg(tunable_attr->dev, "cd_mode_id: %02x%02x%02x%02x, cv_mode_id: %#0= 8x attribute support level: %x\n", + tunable_attr->device_id, tunable_attr->feature_id, tunable_attr->cd_mode= _id, + tunable_attr->type_id, args.arg0, capdata.supported); + + return capdata.supported; + +not_supported: + dev_dbg(tunable_attr->dev, "Attribute id %x not supported\n", args.arg0); + return ret; +} + /* Lenovo WMI Other Mode Attribute macros */ #define __LWMI_ATTR_RO(_func, _name) \ { \ @@ -970,19 +1055,21 @@ static int lwmi_om_fw_attr_add(struct lwmi_om_priv *= priv) } =20 for (i =3D 0; i < ARRAY_SIZE(cd01_attr_groups) - 1; i++) { - err =3D sysfs_create_group(&priv->fw_attr_kset->kobj, - cd01_attr_groups[i].attr_group); - if (err) - goto err_remove_groups; - cd01_attr_groups[i].tunable_attr->dev =3D &priv->wdev->dev; + if (lwmi_attr_01_is_supported(cd01_attr_groups[i].tunable_attr) > 0) { + err =3D sysfs_create_group(&priv->fw_attr_kset->kobj, + cd01_attr_groups[i].attr_group); + if (err) + goto err_remove_groups; + } } return 0; =20 err_remove_groups: while (i--) - sysfs_remove_group(&priv->fw_attr_kset->kobj, - cd01_attr_groups[i].attr_group); + if (lwmi_attr_01_is_supported(cd01_attr_groups[i].tunable_attr) > 0) + sysfs_remove_group(&priv->fw_attr_kset->kobj, + cd01_attr_groups[i].attr_group); =20 kset_unregister(priv->fw_attr_kset); =20 --=20 2.52.0 From nobody Fri Apr 3 00:00:18 2026 Received: from mail-dy1-f176.google.com (mail-dy1-f176.google.com [74.125.82.176]) (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 C1BFE25392A for ; Sun, 15 Feb 2026 06:13:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136027; cv=none; b=QsAF/k+I/RlmMZ5nwkWj3lHghscJVZW4W2lLS8Y1YCvH7iLgmz/yk7j4Q4E/YJuy7B08GqQmuHbhhxHvwUr+SZMWLusX6bdUNoQW/NtmojW6f/KCmPnxXrYF1FuH0jQnS5APBTAG2OB6tItzi7+5NdHooU69xLBpgZxAT0yHaKk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136027; c=relaxed/simple; bh=Fs9nxSRdEPbCXJkY5NgWQzwyUWedOyG0rkTeTAWne30=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NBvQStlSyfCPntO0W/85Yr6xMftNUUuhBCfhLcstmX60Lrba1qiRyS+/ABe8Sb/wMasIfIPLfuCollo7RP6MpZ9DtSxI+NkIoNBTmpK+QDOf9l7fSTY0ayC0jmqlrTQLoLwPaw32X5nw4hItd2wnJgJZuynAOOCJ3cY0PBxk/mA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kFKhCrsj; arc=none smtp.client-ip=74.125.82.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kFKhCrsj" Received: by mail-dy1-f176.google.com with SMTP id 5a478bee46e88-2ba895adfeaso2013866eec.0 for ; Sat, 14 Feb 2026 22:13:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771136025; x=1771740825; 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=hIOlLeyNVXkY5g8zLRZOl2wzw7gNTmnCcL1rHtdQR0k=; b=kFKhCrsjQA4BTsxtTU8UrEccZ4kIc6RGh0Pa+6oVlU7mHDYMX9YsczRuiI3hQRU5IV ZSBJVVn/V93zVNWsbdjId2xfVjETeW7niYLNiVpjp1mSG9LisencHcTs5G+uhd/2FYIy pOb0bTpvRrPa1x8danI3qz/RG9gDKdiix42RAm2LjUQXuXwkpBWPO4uInpMnck2vWczD 36lzGmnhKXKy0OzhcTtF+BodEPi43RlDvh3jxcVlW+IepMDuuvR7ZY6DoY3nPSDSgrBS zUzSBid43ckIQFg3P9l3Lvm/TqiF5+3Wz10ZUpCM1TI6lWAHIX14BTsZxUCCKdEqmg1X E0fw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771136025; x=1771740825; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=hIOlLeyNVXkY5g8zLRZOl2wzw7gNTmnCcL1rHtdQR0k=; b=lLxxHwDX2cK0/QMzgA+GRZ1YqYuGkfyTNOazInTuOZL8mlmqBPQL58nqaReOV6M3HM eUwaYkDcdS+nFdeu7jfb1CFoMI0TOrbLBTYP8DrGC7uq+jpSLqfOToHFBqov7EnFpoRG PD+oSKdta+m5mJurkedgDQG5SRu0n4o3Jj7x12jTqRhD13OoVNcKzY7rvF60QLX7/91d xs49aBsSfj0ezrnpD/ps6SSCr6NalPu+TDVUcYOCcELgCX9T2rpnsFt6ahqBcDYFJeDr OYjHZWyyKQOr+dD5gHgiW2XlDSvCf9ki/zKkWJzz14/264/W6asdcIN4N68r9mJrJruj 0+6Q== X-Forwarded-Encrypted: i=1; AJvYcCVPipqfI++chcUTTP3UDJ1Sl12uJl/15lXmtejTUd4A6tMsQ6xOg7aHNRN3XLQFl4EQm49Oit0SMpyMjxo=@vger.kernel.org X-Gm-Message-State: AOJu0YyMU+VAWQOaTdgdW53Ef6cC3dR65qNL1PERLZrjAr0I2fcl7RYt rpw61768Y0mIuv5YWg/X8H+dGhPqovzoKfAKn4S/yyB4gDbl2YUECv4K X-Gm-Gg: AZuq6aJYwNYNxaZpP4hDWu4wVR70HXckQTLtYpubkAGylFChiPeL20Hvwrj3uXf7pqO jI6r7pCszuIrVROMV48rq5AWyJXecBNMaJyzlQ5oEctt8zWpl5Y9IGv2z7MTyaaHR7oyd8/2q8S o4iRzcrj9iKBADRqWeuWXMV5HMKxN61D3ks7BgzkGLLWe/EEKf3s8PvZmeRrAeU+y+g+SGZRZdz dOSRmakhEgeMsgwlV8ABR7rGc8/fptBsaCDG8MvKFQDLnvFXi5JL0TE/N8xg6/9oIKzdmvTJEz2 mJD23o+uBQmnWzEPw6Z3BEHPwTiYC4KhnTiqawk356UCNq5umJuD/MTTAs32m3KUkT7KKM47Tja NpbujM5Fjb35mbEEOA4gawqMGzHSGuI/MIaqOqMzHUfFYS68/U06rI9E9id0f94lIYaoOejCFdv 7oGKtP1AekVYiVBryioXohSx4dPRP3UO9IFdtQ1ETRi1ng0FjJ7OsFYla6lmPYQbYLSd2HycuN3 3Y= X-Received: by 2002:a05:7301:129b:b0:2b0:2e5:228b with SMTP id 5a478bee46e88-2babc57f80emr1919711eec.33.1771136024957; Sat, 14 Feb 2026 22:13:44 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2bacb577bcasm4759245eec.12.2026.02.14.22.13.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 14 Feb 2026 22:13:44 -0800 (PST) From: "Derek J. Clark" To: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Hans de Goede Cc: Mark Pearson , Armin Wolf , Jonathan Corbet , Rong Zhang , Kurt Borja , "Derek J . Clark" , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/6] platform/x86: lenovo-wmi-other: Add missing CPU tunable attributes Date: Sun, 15 Feb 2026 06:12:56 +0000 Message-ID: <20260215061339.2842486-4-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260215061339.2842486-1-derekjohn.clark@gmail.com> References: <20260215061339.2842486-1-derekjohn.clark@gmail.com> 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" Use an enum for all device Id's and CPU attribute feature ID's, add missing CPU attributes. Signed-off-by: Derek J. Clark Reviewed-by: Mark Pearson --- .../wmi/devices/lenovo-wmi-other.rst | 10 ++ drivers/platform/x86/lenovo/wmi-capdata.h | 5 +- drivers/platform/x86/lenovo/wmi-other.c | 108 +++++++++++++++++- 3 files changed, 117 insertions(+), 6 deletions(-) diff --git a/Documentation/wmi/devices/lenovo-wmi-other.rst b/Documentation= /wmi/devices/lenovo-wmi-other.rst index 01d4711567380..f4763ed66cc6d 100644 --- a/Documentation/wmi/devices/lenovo-wmi-other.rst +++ b/Documentation/wmi/devices/lenovo-wmi-other.rst @@ -68,9 +68,19 @@ Each attribute has the following properties: - type =20 The following firmware-attributes are implemented: + - cpu_oc_stat: CPU Overlocking Status + - cpu_temp: CPU Thermal Load Limit + - ppt_cpu_cl: CPU Cross Loading Power Limit + - ppt_pl1_apu_spl: Platform Profile Tracking APU Sustained Power Limit - ppt_pl1_spl: Platform Profile Tracking Sustained Power Limit + - ppt_pl1_spl_cl: Platform Profile Tracking Cross Loading Sustained Power= Limit + - ppt_pl1_tau: Exceed Duration for Platform Profile Tracking Sustained Po= wer Limit - ppt_pl2_sppt: Platform Profile Tracking Slow Package Power Tracking + - ppt_pl2_sppt_cl: Platform Profile Tracking Cross Loading Slow Package T= racking - ppt_pl3_fppt: Platform Profile Tracking Fast Package Power Tracking + - ppt_pl3_fppt_cl: Platform Profile Tracking Cross Loading Fast Package P= ower Tracking + - ppt_pl4_ipl: Platform Profile Trakcing Instantaneous Power Limit + - ppt_pl4_ipl_cl: Platform Profile Tracking Cross Loading Instantaneous P= ower Limit =20 LENOVO_FAN_TEST_DATA ------------------------- diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x= 86/lenovo/wmi-capdata.h index 27202e2dc8a59..aa48f43cbb43b 100644 --- a/drivers/platform/x86/lenovo/wmi-capdata.h +++ b/drivers/platform/x86/lenovo/wmi-capdata.h @@ -23,7 +23,10 @@ FIELD_PREP(LWMI_ATTR_MODE_ID_MASK, mode) | \ FIELD_PREP(LWMI_ATTR_TYPE_ID_MASK, type)) =20 -#define LWMI_DEVICE_ID_FAN 0x04 +enum lwmi_device_id { + LWMI_DEVICE_ID_CPU =3D 0x01, + LWMI_DEVICE_ID_FAN =3D 0x04, +}; =20 struct component_match; struct device; diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index f3f12303e3798..2986993cbb6a7 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -54,15 +54,22 @@ =20 #define LENOVO_OTHER_MODE_GUID "DC2A8805-3A8C-41BA-A6F7-092E0089CD3B" =20 -#define LWMI_DEVICE_ID_CPU 0x01 - -#define LWMI_FEATURE_ID_CPU_SPPT 0x01 -#define LWMI_FEATURE_ID_CPU_SPL 0x02 -#define LWMI_FEATURE_ID_CPU_FPPT 0x03 +enum lwmi_feature_id_cpu { + LWMI_FEATURE_ID_CPU_SPPT =3D 0x01, + LWMI_FEATURE_ID_CPU_SPL =3D 0x02, + LWMI_FEATURE_ID_CPU_FPPT =3D 0x03, + LWMI_FEATURE_ID_CPU_TEMP =3D 0x04, + LWMI_FEATURE_ID_CPU_APU =3D 0x05, + LWMI_FEATURE_ID_CPU_CL =3D 0x06, + LWMI_FEATURE_ID_CPU_TAU =3D 0x07, + LWMI_FEATURE_ID_CPU_OC =3D 0x08, + LWMI_FEATURE_ID_CPU_IPL =3D 0x09, +}; =20 #define LWMI_FEATURE_ID_FAN_RPM 0x03 =20 #define LWMI_TYPE_ID_NONE 0x00 +#define LWMI_TYPE_ID_CROSSLOAD 0x01 =20 #define LWMI_FEATURE_VALUE_GET 17 #define LWMI_FEATURE_VALUE_SET 18 @@ -559,18 +566,78 @@ static struct tunable_attr_01 ppt_pl1_spl =3D { .type_id =3D LWMI_TYPE_ID_NONE, }; =20 +static struct tunable_attr_01 ppt_pl1_spl_cl =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_SPL, + .type_id =3D LWMI_TYPE_ID_CROSSLOAD, +}; + static struct tunable_attr_01 ppt_pl2_sppt =3D { .device_id =3D LWMI_DEVICE_ID_CPU, .feature_id =3D LWMI_FEATURE_ID_CPU_SPPT, .type_id =3D LWMI_TYPE_ID_NONE, }; =20 +static struct tunable_attr_01 ppt_pl2_sppt_cl =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_SPPT, + .type_id =3D LWMI_TYPE_ID_CROSSLOAD, +}; + static struct tunable_attr_01 ppt_pl3_fppt =3D { .device_id =3D LWMI_DEVICE_ID_CPU, .feature_id =3D LWMI_FEATURE_ID_CPU_FPPT, .type_id =3D LWMI_TYPE_ID_NONE, }; =20 +static struct tunable_attr_01 ppt_pl3_fppt_cl =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_FPPT, + .type_id =3D LWMI_TYPE_ID_CROSSLOAD, +}; + +static struct tunable_attr_01 cpu_temp =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_TEMP, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 ppt_pl1_apu_spl =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_APU, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 ppt_cpu_cl =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_CL, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 ppt_pl1_tau =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_TAU, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 cpu_oc_stat =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_OC, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 ppt_pl4_ipl =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_IPL, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 ppt_pl4_ipl_cl =3D { + .device_id =3D LWMI_DEVICE_ID_CPU, + .feature_id =3D LWMI_FEATURE_ID_CPU_IPL, + .type_id =3D LWMI_TYPE_ID_CROSSLOAD, +}; + struct capdata01_attr_group { const struct attribute_group *attr_group; struct tunable_attr_01 *tunable_attr; @@ -1009,17 +1076,48 @@ static int lwmi_attr_01_is_supported(struct tunable= _attr_01 *tunable_attr) .name =3D _fsname, .attrs =3D _attrname##_attrs \ } =20 +LWMI_ATTR_GROUP_TUNABLE_CAP01(cpu_oc_stat, "cpu_oc_stat", + "Set the CPU overclocking status"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(cpu_temp, "cpu_temp", + "Set the CPU thermal load limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_cpu_cl, "ppt_cpu_cl", + "Set the CPU cross loading power limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl1_apu_spl, "ppt_pl1_apu_spl", + "Set the APU sustained power limit"); LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl1_spl, "ppt_pl1_spl", "Set the CPU sustained power limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl1_spl_cl, "ppt_pl1_spl_cl", + "Set the CPU cross loading sustained power limit"); LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl2_sppt, "ppt_pl2_sppt", "Set the CPU slow package power tracking limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl2_sppt_cl, "ppt_pl2_sppt_cl", + "Set the CPU cross loading slow package power tracking limit"); LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl3_fppt, "ppt_pl3_fppt", "Set the CPU fast package power tracking limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl3_fppt_cl, "ppt_pl3_fppt_cl", + "Set the CPU cross loading fast package power tracking limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl1_tau, "ppt_pl1_tau", + "Set the CPU sustained power limit exceed duration"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl4_ipl, "ppt_pl4_ipl", + "Set the CPU instantaneous power limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl4_ipl_cl, "ppt_pl4_ipl_cl", + "Set the CPU cross loading instantaneous power limit"); + =20 static struct capdata01_attr_group cd01_attr_groups[] =3D { + { &cpu_oc_stat_attr_group, &cpu_oc_stat }, + { &cpu_temp_attr_group, &cpu_temp }, + { &ppt_cpu_cl_attr_group, &ppt_cpu_cl }, + { &ppt_pl1_apu_spl_attr_group, &ppt_pl1_apu_spl }, { &ppt_pl1_spl_attr_group, &ppt_pl1_spl }, + { &ppt_pl1_spl_cl_attr_group, &ppt_pl1_spl_cl }, + { &ppt_pl1_tau_attr_group, &ppt_pl1_tau }, { &ppt_pl2_sppt_attr_group, &ppt_pl2_sppt }, + { &ppt_pl2_sppt_cl_attr_group, &ppt_pl2_sppt_cl }, { &ppt_pl3_fppt_attr_group, &ppt_pl3_fppt }, + { &ppt_pl3_fppt_cl_attr_group, &ppt_pl3_fppt_cl }, + { &ppt_pl4_ipl_attr_group, &ppt_pl4_ipl }, + { &ppt_pl4_ipl_cl_attr_group, &ppt_pl4_ipl_cl }, {}, }; =20 --=20 2.52.0 From nobody Fri Apr 3 00:00:18 2026 Received: from mail-dy1-f178.google.com (mail-dy1-f178.google.com [74.125.82.178]) (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 87E76258ED5 for ; Sun, 15 Feb 2026 06:13:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136028; cv=none; b=tDJC719N/bGTuNZktrjpQ2nku6akpepAHvCum4NReeaM9p8bXnV2J1qfOAHVqPP/uEuhd2h6HQw1k5iHNtpprFUp07n3SL0mH4WoDi3HYpX9n+8ATCeCP7JvfQ2ypr96mVD52zTKVn8o/FuHMwOTiIBEDEBqVnHz3xE1slpcQVo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136028; c=relaxed/simple; bh=aqhY5rKwj8mLz3Kqc/UIPdBqxZUTPOMGzYLOL0qDskc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K6LCv538o4r4RInAhuuQ3tt2PhTvCw4m0PrrSD0bUT7lZRCTF9BS2fKnsvOdpl7tiW4aUaN3k6jGAkRRqmbLWUFuk8WRx9FDEbVYwM3az+K9aFIfjiUPuuQ4PF4Okp+jTrYaMI8G3HL7XGKGU8xVdh/s3PJo+PYcRRLgZqAMZP0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UZ08Y2o1; arc=none smtp.client-ip=74.125.82.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UZ08Y2o1" Received: by mail-dy1-f178.google.com with SMTP id 5a478bee46e88-2b6b0500e06so2397840eec.1 for ; Sat, 14 Feb 2026 22:13:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771136026; x=1771740826; 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=4FodEvOZZ5wtibdy+Cbv3TyVCJ62hdhUOP/vBHTC1fg=; b=UZ08Y2o1dhvBZK5GHOHddedEp3gt5C1YWaUEML+Dp5P4YzGmk1/72DFoU5on65kn/f wvOwmzojlQULfcyc9KxhbE3GxL0SK61i6ZxxKyBS8+yFhHcQPL8NSQbdqRsNLa3asgTq KrHbJIJrweLKtBBQ7r0cOYuA6ir0X7pD8QJ5zQSAz1vkaBhwbaGL+kAqvxsf5rcxBRyl Qp5Uq8f7QGrLIY6qNRuaphpXXGMyahT5jR4SxQ9TQ4nZGxxkgXGFKGCG3IFTxSpwGEKj 8nLpCVxroLrdyxZPJc1bJ6w4Lo/6LGmR67egl/xN5F+iWH1YxwPTaTlrthXK7h1eo1a1 u3yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771136026; x=1771740826; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=4FodEvOZZ5wtibdy+Cbv3TyVCJ62hdhUOP/vBHTC1fg=; b=Q4p7ggK9o6G3fxC1sLa7yomE/uaA/Jbj9EkxXNv6yRywMkduKFP/yOCWHIReuJHMcm 92nDDiJxNjKniEwgPo6E8PFIK3cO/VwunjEDt/Xac9qFOWagOv00Q/ntXvd8UQzgF9gu XmiLoTi7QXOMA5nNH1arZh8TH3iQVJu8VgxPrTRs6pJLRbceEBH8UyutuR77XcIIrSSP Jb8mX1R5MwPqFMpyPiK26jcIX3dk5FHDEYN0wYYxGVatg18ZcV1oj86cPp1yJA6U/Kvu RK8XB0P+pE3r2hvDNdGyfuzmwuXLrYPLdkhGYapwqu250Q+x4TPIBPU0IMgD6agJV4TL 4mkw== X-Forwarded-Encrypted: i=1; AJvYcCXIqVI69TYuaoDzp6/OwHMwEbycYuquAhMCTGjZoyw4lfzbDsAuxTFZaHFQcUE0kIe2tubXbeP4Ip3QnoE=@vger.kernel.org X-Gm-Message-State: AOJu0YyFdP5vuzjopx0IpYJD9vul9qx+td0xBR1iBxDauQ/iHnNyLRgI XUWJlesHT2OlFyvA27aTwSUXrw3o54LxW9iIrCF9eAgAfOIgPHTuXZH+ X-Gm-Gg: AZuq6aLqf1SkW4VYSNt2ul0hcfZvqkiop4kg4amZM9BqXMatGbo2IrIIQxDrE7+D8uB QODTgVxQ9V1M39ulsEJ8oiaoIaAY5GLoDJIxMK9uJBSPThWbD2JmfbF0Op5oizIQTPsHMJzm6+V 7D+a3oCrwQq2LliRBJ/+Z9xjuOTyynvpcolgI0/PkekOL47Ftt/22Dm8d65CH7Zu8WpVRvEj5RC Ys5drVKHLOCx2I4f/acN7eZ121iy3L1k9OJ3Qy3soyOzpV1Ivjj5v6EXjqpUenNFIHvyFHuR+2q Jh8RUTz5xlqqa3m22sd0zD8OjD5yvEA8KI+vQ1hd7BOVzey9b3AWsN5s4y/PzKKco0avFU1EEZl S2vUuIjpwbkLNzXO9F67uOfxFLdMgpVs895M8DBKdWFNvamr1+LHmASz3g21hOJnuN4ssM+t8Cn /CqUTmpK6878Jzxh1KRdvg2H8DxXn2EJqDNfQAg9k0Gh/kRz583gm/10Qshpe8GIhi04Ie/5Wlq Odx3L2P+ABQSA== X-Received: by 2002:a05:7300:d70b:b0:2b8:2910:dc9b with SMTP id 5a478bee46e88-2baba010c12mr2987077eec.3.1771136025589; Sat, 14 Feb 2026 22:13:45 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2bacb577bcasm4759245eec.12.2026.02.14.22.13.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 14 Feb 2026 22:13:45 -0800 (PST) From: "Derek J. Clark" To: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Hans de Goede Cc: Mark Pearson , Armin Wolf , Jonathan Corbet , Rong Zhang , Kurt Borja , "Derek J . Clark" , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/6] platform/x86: lenovo-wmi-other: Add GPU tunable attributes Date: Sun, 15 Feb 2026 06:12:57 +0000 Message-ID: <20260215061339.2842486-5-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260215061339.2842486-1-derekjohn.clark@gmail.com> References: <20260215061339.2842486-1-derekjohn.clark@gmail.com> 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" Use an enum for all GPU attribute feature ID's and add GPU attributes. Signed-off-by: Derek J. Clark Reviewed-by: Mark Pearson --- .../wmi/devices/lenovo-wmi-other.rst | 11 ++ drivers/platform/x86/lenovo/wmi-capdata.h | 1 + drivers/platform/x86/lenovo/wmi-other.c | 115 ++++++++++++++++++ 3 files changed, 127 insertions(+) diff --git a/Documentation/wmi/devices/lenovo-wmi-other.rst b/Documentation= /wmi/devices/lenovo-wmi-other.rst index f4763ed66cc6d..f7564b23bb7f0 100644 --- a/Documentation/wmi/devices/lenovo-wmi-other.rst +++ b/Documentation/wmi/devices/lenovo-wmi-other.rst @@ -70,6 +70,17 @@ Each attribute has the following properties: The following firmware-attributes are implemented: - cpu_oc_stat: CPU Overlocking Status - cpu_temp: CPU Thermal Load Limit + - dgpu_boost_clk: Dedicated GPU Boost Clock + - dgpu_enable: Dedicated GPU Enabled Status + - gpu_didvid: GPU Device Identifier and Vendor Identifier + - gpu_mode: GPU Mode by Power Limit + - gpu_nv_ac_offset: Nvidia GPU AC Total Processing Power Baseline Offset + - gpu_nv_bpl: Nvidia GPU Base Power Limit + - gpu_nv_cpu_boost: Nvidia GPU to CPU Dynamic Boost Limit + - gpu_nv_ctgp: Nvidia GPU Configurable Total Graphics Power + - gpu_nv_ppab: Nvidia GPU Power Performance Aware Boost Limit + - gpu_oc_stat: GPU Overclocking Status + - gpu_temp: GPU Thermal Load Limit - ppt_cpu_cl: CPU Cross Loading Power Limit - ppt_pl1_apu_spl: Platform Profile Tracking APU Sustained Power Limit - ppt_pl1_spl: Platform Profile Tracking Sustained Power Limit diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x= 86/lenovo/wmi-capdata.h index aa48f43cbb43b..b7f9ee7b301a5 100644 --- a/drivers/platform/x86/lenovo/wmi-capdata.h +++ b/drivers/platform/x86/lenovo/wmi-capdata.h @@ -25,6 +25,7 @@ =20 enum lwmi_device_id { LWMI_DEVICE_ID_CPU =3D 0x01, + LWMI_DEVICE_ID_GPU =3D 0x02, LWMI_DEVICE_ID_FAN =3D 0x04, }; =20 diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index 2986993cbb6a7..876834af838e0 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -66,6 +66,20 @@ enum lwmi_feature_id_cpu { LWMI_FEATURE_ID_CPU_IPL =3D 0x09, }; =20 +enum lwmi_feature_id_gpu { + LWMI_FEATURE_ID_GPU_NV_PPAB =3D 0x01, + LWMI_FEATURE_ID_GPU_NV_CTGP =3D 0x02, + LWMI_FEATURE_ID_GPU_TEMP =3D 0x03, + LWMI_FEATURE_ID_GPU_AC_OFFSET =3D 0x04, + LWMI_FEATURE_ID_GPU_OC =3D 0x05, + LWMI_FEATURE_ID_DGPU_BOOST_CLK =3D 0x06, + LWMI_FEATURE_ID_DGPU_EN =3D 0x07, + LWMI_FEATURE_ID_GPU_MODE =3D 0x08, + LWMI_FEATURE_ID_DGPU_DIDVID =3D 0x09, + LWMI_FEATURE_ID_GPU_NV_BPL =3D 0x0a, + LWMI_FEATURE_ID_GPU_NV_CPU_BOOST =3D 0x0b, +}; + #define LWMI_FEATURE_ID_FAN_RPM 0x03 =20 #define LWMI_TYPE_ID_NONE 0x00 @@ -638,6 +652,72 @@ static struct tunable_attr_01 ppt_pl4_ipl_cl =3D { .type_id =3D LWMI_TYPE_ID_CROSSLOAD, }; =20 +static struct tunable_attr_01 gpu_nv_ppab =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_GPU_NV_PPAB, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 gpu_nv_ctgp =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_GPU_NV_CTGP, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 gpu_temp =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_GPU_TEMP, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 gpu_nv_ac_offset =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_GPU_AC_OFFSET, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 gpu_oc_stat =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_GPU_OC, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 dgpu_boost_clk =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_DGPU_BOOST_CLK, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 dgpu_enable =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_DGPU_EN, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 gpu_mode =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_GPU_MODE, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 dgpu_didvid =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_DGPU_DIDVID, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 gpu_nv_bpl =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_GPU_NV_BPL, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + +static struct tunable_attr_01 gpu_nv_cpu_boost =3D { + .device_id =3D LWMI_DEVICE_ID_GPU, + .feature_id =3D LWMI_FEATURE_ID_GPU_NV_CPU_BOOST, + .type_id =3D LWMI_TYPE_ID_NONE, +}; + struct capdata01_attr_group { const struct attribute_group *attr_group; struct tunable_attr_01 *tunable_attr; @@ -1076,6 +1156,7 @@ static int lwmi_attr_01_is_supported(struct tunable_a= ttr_01 *tunable_attr) .name =3D _fsname, .attrs =3D _attrname##_attrs \ } =20 +/* CPU tunable attributes */ LWMI_ATTR_GROUP_TUNABLE_CAP01(cpu_oc_stat, "cpu_oc_stat", "Set the CPU overclocking status"); LWMI_ATTR_GROUP_TUNABLE_CAP01(cpu_temp, "cpu_temp", @@ -1103,10 +1184,44 @@ LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl4_ipl, "ppt_pl4= _ipl", LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl4_ipl_cl, "ppt_pl4_ipl_cl", "Set the CPU cross loading instantaneous power limit"); =20 +/* GPU tunable attributes */ +LWMI_ATTR_GROUP_TUNABLE_CAP01(dgpu_boost_clk, "gpu_boost_clk", + "Set the dedicated GPU boost clock"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(dgpu_didvid, "gpu_didvid", + "Get the GPU device identifier and vendor identifier"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(dgpu_enable, "dgpu_enable", + "Set the dedicated Nvidia GPU enabled status"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(gpu_mode, "gpu_mode", + "Set the GPU mode by power limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(gpu_nv_ac_offset, "gpu_nv_ac_offset", + "Set the Nvidia GPU AC total processing power baseline offset"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(gpu_nv_bpl, "gpu_nv_bpl", + "Set the Nvidia GPU base power limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(gpu_nv_cpu_boost, "gpu_nv_cpu_boost", + "Set the Nvidia GPU to CPU dynamic boost limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(gpu_nv_ctgp, "gpu_nv_ctgp", + "Set the GPU configurable total graphics power"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(gpu_nv_ppab, "gpu_nv_ppab", + "Set the Nvidia GPU power performance aware boost limit"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(gpu_oc_stat, "gpu_oc_stat", + "Set the GPU overclocking status"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(gpu_temp, "gpu_temp", + "Set the GPU thermal load limit"); =20 static struct capdata01_attr_group cd01_attr_groups[] =3D { { &cpu_oc_stat_attr_group, &cpu_oc_stat }, { &cpu_temp_attr_group, &cpu_temp }, + { &dgpu_boost_clk_attr_group, &dgpu_boost_clk }, + { &dgpu_didvid_attr_group, &dgpu_didvid }, + { &dgpu_enable_attr_group, &dgpu_enable }, + { &gpu_mode_attr_group, &gpu_mode }, + { &gpu_nv_ac_offset_attr_group, &gpu_nv_ac_offset }, + { &gpu_nv_bpl_attr_group, &gpu_nv_bpl }, + { &gpu_nv_cpu_boost_attr_group, &gpu_nv_cpu_boost }, + { &gpu_nv_ctgp_attr_group, &gpu_nv_ctgp }, + { &gpu_nv_ppab_attr_group, &gpu_nv_ppab }, + { &gpu_oc_stat_attr_group, &gpu_oc_stat }, + { &gpu_temp_attr_group, &gpu_temp }, { &ppt_cpu_cl_attr_group, &ppt_cpu_cl }, { &ppt_pl1_apu_spl_attr_group, &ppt_pl1_apu_spl }, { &ppt_pl1_spl_attr_group, &ppt_pl1_spl }, --=20 2.52.0 From nobody Fri Apr 3 00:00:18 2026 Received: from mail-dy1-f180.google.com (mail-dy1-f180.google.com [74.125.82.180]) (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 1DC702367D5 for ; Sun, 15 Feb 2026 06:13:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136028; cv=none; b=UVxHossxESTilJOVBlnsNB6KDgiXU9p8ZUZiknRPKs5fav+F85yWs8HKCf1cWqYbf8YqqEpmLgKlXpPr8OW9QB+/IfxM9XWarXFmUvgCysbDG6juzxeh/bxKozpquc9SPdK8FJwesRpbRR1AZ4PsWDQfAx+A3V4TDZodhVMYBkE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136028; c=relaxed/simple; bh=b2kRx70R2FmAvn9oIm5rQmwY1X14JU7VMcFqkLQR9uo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ktw/ifWyS1ayfkiiSzJ6lUkhiBHgVLwYdn5xRCfH4fzqiVJV0RHwU9lu/LyBODNx7ca2JRGo/uV/kcFgH7u4s0lo0b8AYEopyeDAVFjc6+ZIBSuYxVdS7VG1O3FeXwo02vU8W3b4bd9u5bLW21Etol89I8U24AIFJf76JMp5ta4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hY21YjMo; arc=none smtp.client-ip=74.125.82.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hY21YjMo" Received: by mail-dy1-f180.google.com with SMTP id 5a478bee46e88-2ba6aa57d5fso2206705eec.1 for ; Sat, 14 Feb 2026 22:13:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771136026; x=1771740826; 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=O8cAURfQXVGK/iep/lFxjpueu/CHLixKteAdv7jcw8Q=; b=hY21YjMoMN4WjihCcxBBNkNS+yw8ExUGx/Vlgnm0NJP7/8SjH7aCwn1A5szb5sFhSl Htbqggbz8RPD9nKso298N0hNa2k45LWTkzojTFg1kqutdUui8hBaRYtOXtANgve6z2qB cQLhnU0nEfOaAjFwuwqtbOXK2bipROHqpvsMi3PvU1NY87Evmzb/9ioLguBnITpj4lPr zFYCYuiOd41bVZh2wc4+K53e6gPAFdbz3sNvvsHzRVKiIuCOCGe/300WhLmL4MSB5qn3 eXCcfXXpXDlSMzLCK6IAv1Tj4pCSObJ/whikCPl5pue2xINNoCKCriLq4zeiGBidGQVm hh7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771136026; x=1771740826; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=O8cAURfQXVGK/iep/lFxjpueu/CHLixKteAdv7jcw8Q=; b=tGCp5uMTXU7UC1LYkDqKNfvddaLwfCzrbPZBN970c40j6BbPrhPWNO78ineqCMSwqc Lqnvz20k7ep/ORN0qImDq7KQz/ueBQxx5HBGMesDHCqwCqvAOZld4L9kPPouRgk9QN9z ofPTy0pciBvR7p1mHYv1T8gYNaGMvaJb5qRZudexg6pLpPBk4pl98d5LU+OUvOV4Iutg MffnEqIK1FNwfjMM65HBb4oDXgiac8afY1FK+mk73YibW37+tANjq3xBJ9vN0ip5uaWL UfofQJp067PsVQbsjoe1XioBNMqRbgZkS4ywdg2+E6e2Xz//BI9XlXyFopigjuliNNjE BoXw== X-Forwarded-Encrypted: i=1; AJvYcCVBz0EoI/PW8HNChIssyZerNkmUeQG1A8FNguBEZPISjFkU6jdDiHjfOiXZtxpCYcBI9cr5fdj+FAECkOU=@vger.kernel.org X-Gm-Message-State: AOJu0Yye8BcWZp8y9xFsTAJMEWNJgTBvSO9e/b1s5lmR/t7gVLAgqR2W bpopXv0/4+pxEJw81HVyp0VFyqndVayDKztN6+i1J0joTR4XuZr6GfQuQxdftQ== X-Gm-Gg: AZuq6aID3sYwBaUnN7ThDrpJrPVsGdsRzkE+7tEru4li7lR8wvq7gTMeUPVIQTH8cCd uOlsB2gTyoYlRIrtWvV7i4xHhlog64sTGy2BIsDNhIuxMuxlPiyQdOmZi7K/g9di0aMnIev0VJY 8HRMKvNaAlQ56/t9uSNiVaxL4xObsP6Lo0EEGKhXbkonJfYewot6pZXNfC1eXhSFGei/BGlqsdx wHjnKG9Bs519JNL8HbP/WQ+7IJF3GpY85KejtTlvtUSiqnWLTXfF+kiu0XIl/2rjhOI4ItoIG9b 1PQ4bqAahb3CrwLuuxLFEPX1CdSSWM1z1l45Fm3JgGWJ/JCzDO0MRaLRbEi9XMIFmTXgGeSiDcp rPFHirBy8HYCeMXiPrmiHSFVWQEGEN7/9igBj0KHn8DOhIQh0LYGdLnlTM5Si3dvyLWvn42jJOB Fz8AO+ReP19zLGW2ZKGX3yh/lcRfh3yj5MjrUrMkTWsUXUhehNG4vIr5xYPp5KQIWqdu6a91+e5 Gw= X-Received: by 2002:a05:7301:1007:b0:2ba:68d6:47ae with SMTP id 5a478bee46e88-2bac97cb47bmr1305341eec.34.1771136026240; Sat, 14 Feb 2026 22:13:46 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2bacb577bcasm4759245eec.12.2026.02.14.22.13.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 14 Feb 2026 22:13:45 -0800 (PST) From: "Derek J. Clark" To: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Hans de Goede Cc: Mark Pearson , Armin Wolf , Jonathan Corbet , Rong Zhang , Kurt Borja , "Derek J . Clark" , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 5/6] platform-x86: lenovo-wmi-other: Consolidate name into single const Date: Sun, 15 Feb 2026 06:12:58 +0000 Message-ID: <20260215061339.2842486-6-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260215061339.2842486-1-derekjohn.clark@gmail.com> References: <20260215061339.2842486-1-derekjohn.clark@gmail.com> 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 next patch a power supply extension is added which requires a name attribute. Instead of creating a third const macro with the same information, replace LWMI_OM_FW_ATTR_BASE_PATH and LWMI_OM_HWMON_NAME with LWMI_OM_NAME and use that everywhere. Signed-off-by: Derek J. Clark Reviewed-by: Mark Pearson --- drivers/platform/x86/lenovo/wmi-other.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index 876834af838e0..8e52f692f8605 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -92,14 +92,13 @@ enum lwmi_feature_id_gpu { #define LWMI_FAN_NR 4 #define LWMI_FAN_ID(x) ((x) + LWMI_FAN_ID_BASE) =20 +#define LWMI_FAN_DIV 100 + #define LWMI_ATTR_ID_FAN_RPM(x) \ LWMI_ATTR_ID(LWMI_DEVICE_ID_FAN, LWMI_FEATURE_ID_FAN_RPM, \ LWMI_GZ_THERMAL_MODE_NONE, LWMI_FAN_ID(x)) =20 -#define LWMI_FAN_DIV 100 - -#define LWMI_OM_FW_ATTR_BASE_PATH "lenovo-wmi-other" -#define LWMI_OM_HWMON_NAME "lenovo_wmi_other" +#define LWMI_OM_NAME "lenovo-wmi-other" =20 static BLOCKING_NOTIFIER_HEAD(om_chain_head); static DEFINE_IDA(lwmi_om_ida); @@ -454,7 +453,7 @@ static void lwmi_om_hwmon_add(struct lwmi_om_priv *priv) } =20 priv->hwmon_dev =3D hwmon_device_register_with_info(&priv->wdev->dev, - LWMI_OM_HWMON_NAME, priv, + LWMI_OM_NAME, priv, &lwmi_om_hwmon_chip_info, NULL); if (IS_ERR(priv->hwmon_dev)) { @@ -1253,8 +1252,7 @@ static int lwmi_om_fw_attr_add(struct lwmi_om_priv *p= riv) =20 priv->fw_attr_dev =3D device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), NULL, "%s-%u", - LWMI_OM_FW_ATTR_BASE_PATH, - priv->ida_id); + LWMI_OM_NAME, priv->ida_id); if (IS_ERR(priv->fw_attr_dev)) { err =3D PTR_ERR(priv->fw_attr_dev); goto err_free_ida; --=20 2.52.0 From nobody Fri Apr 3 00:00:18 2026 Received: from mail-dy1-f181.google.com (mail-dy1-f181.google.com [74.125.82.181]) (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 C8A36261B78 for ; Sun, 15 Feb 2026 06:13:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136029; cv=none; b=CrV+A4/Utwl5SVJhrtWL/WIt/FXGNhhOKs6AFprMER6NRMglj9dToRTSjy7GYH/kEM3ncwGaME+kiM6/RGGP65D+snMI4iLAK5lP7Iyz9UGvljUSh7VW2gdNheboW+YIam0UhJrlhRa2rbsIbeEo8QQ3qW3MmOySNaEns2gMXsM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771136029; c=relaxed/simple; bh=wZ9xabQUkHqtqC3jkEGT+Zqanc8nlXjAOp1zXQUfI4w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pO6Jq7iEn2pTqKcN7IhisA+FGrqcN2K2rOVH34Gm0lpOdSyBolL0vP3ylNXAOA7SlPBzQ6cWQPSbegy6Hgo9xZI6K/o6Si4b7YL1MJfzG0vnIKu9Be/N0Bl5idxP7z7KvYN5dLtNPKzkkAni55HqH+6No7Exve2etFJRDXqrWVQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=l4HHd1/R; arc=none smtp.client-ip=74.125.82.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l4HHd1/R" Received: by mail-dy1-f181.google.com with SMTP id 5a478bee46e88-2b4520f6b32so2520743eec.0 for ; Sat, 14 Feb 2026 22:13:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771136027; x=1771740827; 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=HnG6U+oeOzP9TzbbrF5UKJqUPdR6+ZgY34ulfRGGHcc=; b=l4HHd1/RvngzI3/rP/H563Q1EfHk/ffQrSihMuj+BaKNvVcA5JEN3MV8/vSYmLiQL6 OajvCOd2iUrCjmmfMGFOP9KTPGQy/f9mOTlNF580uBm0bWvrssO7uATClYBUK6XnLJd6 WGOxOfVaWr4XZbjibFHxWr6VaGQtFbte4DYU7hWiS+faQ7zA86zbBODVrJd6Dk6sKKbc AzVxeuM7CFppX9sb7wmFIY0GYmhKMayfUFJHKdhLZnRqziTuCZuAfscM8T755GyoXWcQ oWtb42iNOuepFwvXuPNJ0gqXXRfY8AIOBmW+Dlof9dR68fBOaxnQdr5hJvvd2EP1t+g+ WTjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771136027; x=1771740827; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=HnG6U+oeOzP9TzbbrF5UKJqUPdR6+ZgY34ulfRGGHcc=; b=jkuDJub82+Xs7fc04o7lWZNPE0pH0x7LQEvUbW2pf6orH+2yuDZMyfq1OOdM42zQcx JAA7KWsam+QaEQyBI8zYsD6t5iiqzxx9U4mNK2h7Fx8LlUee3jNBZqh0uAEADAIfsVYO tSyoejJmQKnGQIG4p5R6OcJJSKbHq6TM55TJ7lXYwCvdSp9jHE2kzC+417pFr//gjRIm 6VjnO94jbZ8JZ6F9lG2MDRZLpDGvuFSlwX/KvDoThTktoPWyPJ98WtG2tK9szFB+wYp4 K2FlGsVL18h1egoAQXJCAW233dfybjUo6jcswQLB258Fete4axqnPzhw/GudmDjovOeW VX4Q== X-Forwarded-Encrypted: i=1; AJvYcCVBoSyJvNTW9jvPKM638brLlgFZPj1t17tnBFCm8D0WtWzTJJukD36eGaUGLuevMDkIzbcR7rhM41JA9/c=@vger.kernel.org X-Gm-Message-State: AOJu0YxHWl//45XXBhLmTu1DYuo8/HlZD/giMKpdEwB3/1f5d3XxxDOd y7qXMT0qK65GObjHHDDIMqn41WwEMQlA9NGaYUO8w2lWH02+7735Dgz4 X-Gm-Gg: AZuq6aIe4OPjrKcWLsrghJnMfrEGBMIHFp9kX+0elFRFiVRxn4iKzQu/eU0EW1G5GbQ LG8U7eixmPfTcXBhoEepBMulEoXQBXK3ZgaJgiZfSeZm3yJDui165gpPAKl2+IhpA5wnAFTzKWS yVQ+XwpNILdXZNr6P64gsrLrov+ZmNUKnOL5Xs/iJ7gyjGMLBxYgLYHCwsTZfGsZFtCcFcK10I8 OgHJ783jNL9BwW8iZ1RiLXf06OeO3Z7wl3BjeJnw0F7Dec1+FBuhJ7pTot9duaQTfu9iFHiXIUg CfVLSs7y1NnF9izITRS+vl/1zH8frLvQJ9RMfk/uxpodqygSJNglkcxgKbTneCqe7NZ1pt4c/4K W2l8uLFg5xGHLgfMRvL2mT9RAwOYov2+fRWyiOc+ChdUoCIijcao2OlfQ4hObQxk0vO7sVKcOE7 y6zx7JJf+ZG8LkeItJ6vV2XZp9S3A+nHA4BWEAjEhqczZ/ZHccOd35N6EnSNf3P/DbF8ddJfYBr yE= X-Received: by 2002:a05:7300:f082:b0:2ba:70d6:e371 with SMTP id 5a478bee46e88-2babc3d06afmr2844941eec.19.1771136026904; Sat, 14 Feb 2026 22:13:46 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2bacb577bcasm4759245eec.12.2026.02.14.22.13.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 14 Feb 2026 22:13:46 -0800 (PST) From: "Derek J. Clark" To: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Hans de Goede Cc: Mark Pearson , Armin Wolf , Jonathan Corbet , Rong Zhang , Kurt Borja , "Derek J . Clark" , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 6/6] platform/x86: lenovo-wmi-other: Add WMI battery charge limiting. Date: Sun, 15 Feb 2026 06:12:59 +0000 Message-ID: <20260215061339.2842486-7-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260215061339.2842486-1-derekjohn.clark@gmail.com> References: <20260215061339.2842486-1-derekjohn.clark@gmail.com> 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" Add charge-type power supply extension for devices that support WMI based charge enable/disable. Lenovo Legion devices that implement function ID and capdata 00 ID 0x03010001 are able to enable or disable charging through the lenovo-wmi-other interface. The ideapad_laptop driver conflicts with this if it can also provide the attribute, so we have to get the acpi_handle and check for the same ACPI methods that enable the feature in that driver. The ACPI method is more reliable from my testing when both are present, so there is no need to modify the ideapad_laptop driver instead. Signed-off-by: Derek J. Clark Reviewed-by: Mark Pearson --- drivers/platform/x86/lenovo/wmi-capdata.h | 1 + drivers/platform/x86/lenovo/wmi-other.c | 229 ++++++++++++++++++++++ 2 files changed, 230 insertions(+) diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x= 86/lenovo/wmi-capdata.h index b7f9ee7b301a5..00471551e7d60 100644 --- a/drivers/platform/x86/lenovo/wmi-capdata.h +++ b/drivers/platform/x86/lenovo/wmi-capdata.h @@ -26,6 +26,7 @@ enum lwmi_device_id { LWMI_DEVICE_ID_CPU =3D 0x01, LWMI_DEVICE_ID_GPU =3D 0x02, + LWMI_DEVICE_ID_PSU =3D 0x03, LWMI_DEVICE_ID_FAN =3D 0x04, }; =20 diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index 8e52f692f8605..7b6074062a09d 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -26,6 +26,7 @@ * - binding to Capability Data 00 and Fan */ =20 +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #include #include =20 @@ -80,10 +82,17 @@ enum lwmi_feature_id_gpu { LWMI_FEATURE_ID_GPU_NV_CPU_BOOST =3D 0x0b, }; =20 +enum lwmi_feature_id_psu { + LWMI_FEATURE_ID_PSU_INSTANT_MODE =3D 0x01, + LWMI_FEATURE_ID_PSU_CHARGE_MODE =3D 0x02, +}; + #define LWMI_FEATURE_ID_FAN_RPM 0x03 =20 #define LWMI_TYPE_ID_NONE 0x00 #define LWMI_TYPE_ID_CROSSLOAD 0x01 +#define LWMI_TYPE_ID_PSU_AC 0x01 +#define LWMI_TYPE_ID_PSU_PD 0x02 =20 #define LWMI_FEATURE_VALUE_GET 17 #define LWMI_FEATURE_VALUE_SET 18 @@ -94,10 +103,17 @@ enum lwmi_feature_id_gpu { =20 #define LWMI_FAN_DIV 100 =20 +#define LWMI_CHARGE_MODE_ENABLED 0x00 +#define LWMI_CHARGE_MODE_DISABLED 0x01 + #define LWMI_ATTR_ID_FAN_RPM(x) \ LWMI_ATTR_ID(LWMI_DEVICE_ID_FAN, LWMI_FEATURE_ID_FAN_RPM, \ LWMI_GZ_THERMAL_MODE_NONE, LWMI_FAN_ID(x)) =20 +#define LWMI_ATTR_ID_PSU(feat, type) \ + LWMI_ATTR_ID(LWMI_DEVICE_ID_PSU, feat, \ + LWMI_GZ_THERMAL_MODE_NONE, type) + #define LWMI_OM_NAME "lenovo-wmi-other" =20 static BLOCKING_NOTIFIER_HEAD(om_chain_head); @@ -138,6 +154,8 @@ struct lwmi_om_priv { bool capdata00_collected : 1; bool capdata_fan_collected : 1; } fan_flags; + + struct acpi_battery_hook battery_hook; }; =20 /* @@ -562,6 +580,216 @@ static void lwmi_om_fan_info_collect_cd_fan(struct de= vice *dev, struct cd_list * lwmi_om_hwmon_add(priv); } =20 +/* =3D=3D=3D=3D=3D=3D=3D=3D Power Supply Extension (component: lenovo-wmi-= capdata 00) =3D=3D=3D=3D=3D=3D=3D=3D */ + +/** + * lwmi_psy_ext_get_prop() - Get a power_supply_ext property + * @ps: The battery that was extended + * @ext: The extension + * @ext_data: Pointer the lwmi_om_priv drvdata + * @prop: The property to read + * @val: The value to return + * + * Writes the given value to the power_supply_ext property + * + * Return: 0 on success, or an error + */ +static int lwmi_psy_ext_get_prop(struct power_supply *ps, + const struct power_supply_ext *ext, + void *ext_data, + enum power_supply_property prop, + union power_supply_propval *val) +{ + struct lwmi_om_priv *priv =3D ext_data; + struct wmi_method_args_32 args; + u32 retval; + int ret; + + args.arg0 =3D LWMI_ATTR_ID_PSU(LWMI_FEATURE_ID_PSU_INSTANT_MODE, LWMI_TYP= E_ID_PSU_AC); + + ret =3D lwmi_dev_evaluate_int(priv->wdev, 0x0, LWMI_FEATURE_VALUE_GET, + (unsigned char *)&args, sizeof(args), + &retval); + if (ret) + return ret; + + dev_dbg(&priv->wdev->dev, "Got return value %x for property %x\n", retval= , prop); + + if (retval =3D=3D LWMI_CHARGE_MODE_DISABLED) + val->intval =3D POWER_SUPPLY_CHARGE_TYPE_LONGLIFE; + else + val->intval =3D POWER_SUPPLY_CHARGE_TYPE_STANDARD; + + return 0; +} + +/** + * lwmi_psy_ext_set_prop() - Set a power_supply_ext property + * @ps: The battery that was extended + * @ext: The extension + * @ext_data: Pointer the lwmi_om_priv drvdata + * @prop: The property to write + * @val: The value to write + * + * Writes the given value to the power_supply_ext property + * + * Return: 0 on success, or an error + */ +static int lwmi_psy_ext_set_prop(struct power_supply *ps, + const struct power_supply_ext *ext, + void *ext_data, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + struct lwmi_om_priv *priv =3D ext_data; + struct wmi_method_args_32 args; + + args.arg0 =3D LWMI_ATTR_ID_PSU(LWMI_FEATURE_ID_PSU_INSTANT_MODE, LWMI_TYP= E_ID_PSU_AC); + if (val->intval =3D=3D POWER_SUPPLY_CHARGE_TYPE_LONGLIFE) + args.arg1 =3D LWMI_CHARGE_MODE_DISABLED; + else + args.arg1 =3D LWMI_CHARGE_MODE_ENABLED; + + dev_dbg(&priv->wdev->dev, "Attempting to set %#08x for property %x to %x\= n", + args.arg0, prop, args.arg1); + + return lwmi_dev_evaluate_int(priv->wdev, 0x0, LWMI_FEATURE_VALUE_SET, + (unsigned char *)&args, sizeof(args), NULL); +} + +/** + * lwmi_psy_prop_is_writeable() - Determine if the property is supported + * @ps: The battery that was extended + * @ext: The extension + * @ext_data: Pointer the lwmi_om_priv drvdata + * @prop: The property to check + * + * Checks capdata 00 to determine if the property is supported. + * + * Return: Support level, or false + */ +static int lwmi_psy_prop_is_writeable(struct power_supply *ps, + const struct power_supply_ext *ext, + void *ext_data, + enum power_supply_property prop) +{ + struct lwmi_om_priv *priv =3D ext_data; + struct capdata00 capdata; + u32 attribute_id =3D LWMI_ATTR_ID_PSU(LWMI_FEATURE_ID_PSU_INSTANT_MODE, L= WMI_TYPE_ID_PSU_AC); + int ret; + + ret =3D lwmi_cd00_get_data(priv->cd00_list, attribute_id, &capdata); + if (ret) + return false; + + dev_dbg(&priv->wdev->dev, "Battery charge mode (%#08x) support level: %x\= n", + attribute_id, capdata.supported); + + return capdata.supported; +} + +static const enum power_supply_property lwmi_psy_ext_props[] =3D { + POWER_SUPPLY_PROP_CHARGE_TYPES, +}; + +static const struct power_supply_ext lwmi_psy_ext =3D { + .name =3D LWMI_OM_NAME, + .properties =3D lwmi_psy_ext_props, + .num_properties =3D ARRAY_SIZE(lwmi_psy_ext_props), + .charge_types =3D (BIT(POWER_SUPPLY_CHARGE_TYPE_STANDARD) | + BIT(POWER_SUPPLY_CHARGE_TYPE_LONGLIFE)), + .get_property =3D lwmi_psy_ext_get_prop, + .set_property =3D lwmi_psy_ext_set_prop, + .property_is_writeable =3D lwmi_psy_prop_is_writeable, +}; + +/** + * lwmi_add_battery() - Connect the power_supply_ext + * @battery: The battery to extend + * @hook: The driver hook used to extend the battery + * + * Return: 0 on success, or an error. + */ +static int lwmi_add_battery(struct power_supply *battery, struct acpi_batt= ery_hook *hook) +{ + struct lwmi_om_priv *priv =3D container_of(hook, struct lwmi_om_priv, bat= tery_hook); + + return power_supply_register_extension(battery, &lwmi_psy_ext, &priv->wde= v->dev, priv); +} + +/** + * lwmi_remove_battery() - Disconnect the power_supply_ext + * @battery: The battery that was extended + * @hook: The driver hook used to extend the battery + * + * Return: 0 on success, or an error. + */ +static int lwmi_remove_battery(struct power_supply *battery, struct acpi_b= attery_hook *hook) +{ + power_supply_unregister_extension(battery, &lwmi_psy_ext); + return 0; +} + +/** + * lwmi_acpi_match() - Attempts to return the ideapad acpi handle + * @handle: The ACPI handle that manages battery charging + * @lvl: Unused + * @context: Void pointer to the acpi_handle object to return + * @retval: Unused + * + * Checks if the ideapad_laptop driver is going to manage charge_type firs= t, + * then if not, hooks the battery to our WMI methods. + * + * Return: AE_CTRL_TERMINATE if found, AE_OK if not found. + */ +static acpi_status lwmi_acpi_match(acpi_handle handle, u32 lvl, + void *context, void **retval) +{ + if (!handle) + return AE_OK; + + acpi_handle *ahand =3D context; + *ahand =3D handle; + + return AE_CTRL_TERMINATE; +} + +/** + * lwmi_om_ps_ext_init() - Hooks power supply extension to device battery + * @priv: Driver private data + * + * Checks if the ideapad_laptop driver is going to manage charge_type firs= t, + * then if not, hooks the battery to our WMI methods. + */ +static void lwmi_om_ps_ext_init(struct lwmi_om_priv *priv) +{ + static const char * const ideapad_hid =3D "VPC2004"; + acpi_handle handle =3D NULL; + int ret; + + /* Deconflict ideapad_laptop driver */ + ret =3D acpi_get_devices(ideapad_hid, lwmi_acpi_match, &handle, NULL); + if (ret) + return; + + if (!handle) + return; + + if (acpi_has_method(handle, "GBMD") && acpi_has_method(handle, "SBMC")) { + dev_dbg(&priv->wdev->dev, "ideapad_laptop driver manages battery for dev= ice.\n"); + return; + } + + /* Add battery hooks */ + priv->battery_hook.add_battery =3D lwmi_add_battery, + priv->battery_hook.remove_battery =3D lwmi_remove_battery, + priv->battery_hook.name =3D "Lenovo WMI Other Battery Extension", + + ret =3D devm_battery_hook_register(&priv->wdev->dev, &priv->battery_hook); + if (ret) + dev_err(&priv->wdev->dev, "Error during battery hook: %i\n", ret); +} + /* =3D=3D=3D=3D=3D=3D=3D=3D fw_attributes (component: lenovo-wmi-capdata 0= 1) =3D=3D=3D=3D=3D=3D=3D=3D */ =20 struct tunable_attr_01 { @@ -1344,6 +1572,7 @@ static int lwmi_om_master_bind(struct device *dev) return -ENODEV; =20 lwmi_om_fan_info_collect_cd00(priv); + lwmi_om_ps_ext_init(priv); =20 return lwmi_om_fw_attr_add(priv); } --=20 2.52.0