From nobody Sun Apr 5 19:41:55 2026 Received: from mail-dl1-f45.google.com (mail-dl1-f45.google.com [74.125.82.45]) (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 BB9761519AC for ; Tue, 24 Feb 2026 04:32:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907530; cv=none; b=q4sV67/roLoFFbg0pQUf/0eRAoU2kJuex1Lmk0dFunTxH6Fpv177Yd2DGlih/UljDh7otRDFkA8KXUSegnrAa0ljnkIgCKOcmyUigoy5tqNJgDgt0iIuqPw9pYQ07yV6hN54ZjrHFGyCJJoq/3c+a9/ZQ+hD9zcVgqSpL/h5eaU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907530; c=relaxed/simple; bh=LqAU7VJS3qzJAT41dFUmYBdeix9X3weX9TYWggTt6dA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MomOUdRbh2/CpCEN3cIvVpnhB4PoSKtu2lmH4DX5W0nWBZvmHd60yldaI41BM3z40K7Vn8+Wtz0fqI2iWnkWnMVJq5833E48lvuvxfJn3uksRAJB+ub7E61A9poVOdWjMPyqhBUfek0BBlRTwS079iOLo04lEQxcoXwxuWBjOyc= 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=Up+/Jmsc; arc=none smtp.client-ip=74.125.82.45 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="Up+/Jmsc" Received: by mail-dl1-f45.google.com with SMTP id a92af1059eb24-127380532eeso8068790c88.1 for ; Mon, 23 Feb 2026 20:32:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771907528; x=1772512328; 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=eMalNm3TsX32uk+X6/tnYsZe/zOmNCWUKfIF8l7UvOE=; b=Up+/JmscpqsLE2JXSBxNoFbMtiY9zE0kBm4uVGtr+wbPbf1BHU0x6NbKmCMM1Rw/qB bNYeSX24qJ4sMs9NLkdAJsRx5l08xmmiGEk1BQ+h9w0EhvTAiT/brYD9f80PSEzcbDN6 q8sYdYMpnNwFEF0r1pxXuOPT8KapVCbfwSZQrHo4O4SqqpwjUsJSVcRBMhdW0kSo3t+U OWVdAUkcmqs2dQOavk4jxHy5E57nEwsaFVGQbwLRcjIoIkK8i0pjzffGX+kiaXW1SHWw mSjLe2B9jtnzYq6vAQ2kXmT+MX2UNrLFYiYsZ0zh3V4Of4cMUXk7pMqskTLNDaEkodqd Qa6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771907528; x=1772512328; 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=eMalNm3TsX32uk+X6/tnYsZe/zOmNCWUKfIF8l7UvOE=; b=E58NO0Azhxj5GjH1x5nBTHtoRPfZc1FriqPCHIXPCfLnn+7wY4Go07W5f5E14RTBb9 nxax/A7J2CEgvuiy+cZuUfsoUUnAVKrUDr47ndlzhPHzIRtSqfYjHsvUQPGkcEHP7u/8 yfPA+IFFf8QWUk/9upwYhczCKkEx4+01uwl9GqnGYwIet/76Ct3DhPliCUrGuj9fmv5J Fsy86LlE0M8wTumRhgZcOhML206/mmDjFkkeruzs0DZUkmjYuz1CagGx/IvEElxP/51K FCkxuar3r8YNijk/qPryw2m8dw3v28f9RQh1AWq0ZrbQNRly41yj7+qAVv8vQyOBEpyc EA3A== X-Forwarded-Encrypted: i=1; AJvYcCVPQO2DqCtADrhuBM98TH+U47ksD5uolo6+RecfCwZ1aj/y15fjaN3/G+jp+8+RleHl+HrmGxMdbQMcq+k=@vger.kernel.org X-Gm-Message-State: AOJu0YxYTu/vbYRfDhQsuPipUdfulAxgN2UCbHXzra1XkOEoovGXINnA 2aIyOyT1lLNQB2QjmjhqoEh0Sg1mP49qTPBt2spkRaQa55rc2xisJpoM X-Gm-Gg: AZuq6aLDnU7IzVHSMGsqsdtPG6bReqNOvQK99x6L2JnEigrW6cyuhr2mZ8D5RII5cPK 2Mw7N8qVIuS0kce9+fGgRthJw6X8oYGeeWcCf+Xr+PVzbMnv1KyBA6BPvNKcJmcThf5Kz9ost3G 91zbslAw9x93V/cgpvou5XWSAnB8prfy9aF7coKw50UjiEulMHU+XS1uf+QqaCNeggK3LH0au68 6A7oG3qYH8pGtrMG/h8Fm1kdRc3dF77xhZFPmNKNs+8+ZJpjkYPbQR6Ah+iQnptVU5/ZfnSAZIh PG+qq53xDyr3tkAWuyifVU0VGyMXLZ1j2fbY9OVx0JVgxMUeAAwh9ccLYM1JfWgw+PM373u7JRI 286oWsPhqEoO6hYzqWIsrtpuTxIObSgijEyaE3QCMG1lUOixqcFJ1UyvoT+N2tGpSi+HMtqbcfL sPnJ3W3xOZ5/R3w1gwC9uO7sHNWfLHfRygRQsidBSpdSXpKWeuB19PySpoGdB7IednAslCbtCvr Fk= X-Received: by 2002:a05:7022:4584:b0:122:2f4:b24b with SMTP id a92af1059eb24-1276ad1a72bmr4729717c88.25.1771907527861; Mon, 23 Feb 2026 20:32:07 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1276af7b4c7sm9607887c88.9.2026.02.23.20.32.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Feb 2026 20:32:07 -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 v3 1/6] platform/x86: lenovo-wmi-other: Add LWMI_ATTR_ID Macro Date: Tue, 24 Feb 2026 04:31:55 +0000 Message-ID: <20260224043200.2680384-2-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260224043200.2680384-1-derekjohn.clark@gmail.com> References: <20260224043200.2680384-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. Reviewed-by: Mark Pearson Signed-off-by: Derek J. Clark Reviewed-By: Rong Zhang --- 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 8c1df3efcc55..27202e2dc8a5 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 6b163a5eeb95..ddb919cf6c36 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 6040f45aa2b0..95886df39c8d 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), --=20 2.52.0 From nobody Sun Apr 5 19:41:55 2026 Received: from mail-dl1-f49.google.com (mail-dl1-f49.google.com [74.125.82.49]) (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 60F7A1A8F84 for ; Tue, 24 Feb 2026 04:32:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907530; cv=none; b=kUrrT1LAmcg5N2SbgDAtNvN1I2pjNyKjkn6rQFhYMynGdA8MwIAUlmrazuW3DIKB9cwVxf5UYlD1V82a28aRl7lrJe/3TAqfOnrkz1xcZOWdGDX6X9+8xuYeY4ZmDeNxs+/87kHo7U4pypRTcHNlScGGBbxrpCsp4kT8CorVHYc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907530; c=relaxed/simple; bh=GRWHAjsDZQLJvOahwj/eKOpyw5l4+67wzGbbkgCj/5I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KssP7z1sNMKey1execkf3p1YAG9VOKfD/TSca5BmcGF/+2xsyeVNBF5iFVKBk6I2Knc8BLxam0ZkWCQh2uVbqqB97NgoXbdS/r761BQTa2XH0eJtpmxLj5cjFeiBBNcxdC8zcrAZq7jXdgf56QJuoVT2sTfgvsrB/KgylySbL1M= 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=Xi40oL7S; arc=none smtp.client-ip=74.125.82.49 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="Xi40oL7S" Received: by mail-dl1-f49.google.com with SMTP id a92af1059eb24-1274204434bso4000624c88.1 for ; Mon, 23 Feb 2026 20:32:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771907528; x=1772512328; 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=HILna4J1JaHWKh8vgw8UaORe+PQkERxPpDpgU+CN4GE=; b=Xi40oL7SqavdzaORV/Mm4GDXgTQwQ8G/OaRMj2eI1AAn57XcwuGPCtJTt0JhV6PLvy JVbGK/eRg07ku8cLnO9VZyxFBZ/23mUERjWd3KWFukDqRF5CuDiCIohFNYR26sOUKFgL 7tF0MNKCVP9obNpGGbIUTIpq4P7IxOQjmc4aYVTVLOoyh8z+GFoo9EYXHj1XwQ7LxlHQ ALYgZ3dDJC6idQ3N2RDThnn9DLUGz3lVjKOcze/rDhlUtO6AG1egeWC+P60ZpZ1bScZT FGtPTFMBKu6Rz6TIlWP7iD/GJVrEXZyX43BYeONPBHGH7KAHF28TE7B6p0ODBEYrq933 KQww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771907528; x=1772512328; 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=HILna4J1JaHWKh8vgw8UaORe+PQkERxPpDpgU+CN4GE=; b=n68apdsBtGBqwA6GcNlYk6CmTkK4Mkbmi8bwZQnfjcODyx7/188Fyf5tUnBDOzOk0x WX/PdUSX8Gks4v2iTSrAp1VQio410iir/YF4AKHpSLKUt2JNjrRbGVGe8zKNPYWMDrxY CUODe3rbXT4unjck7Ahl13u+axGboiOE2A0CarrjF4tOxIJ8VOHa36txz7aM6t2zvif7 vNN4OQliLE4Lu5y119nfOHx1f/O06P9++8xQwkJ6yT5jddvkImtR8y9gRzciJTxxim9s Uba4oBuvJH5Ew0/jylxBJxJCeH2CBIRCkzE+Bgw6if7hH84V+ODgxI6Rs8lTKDn+z+DB FkNA== X-Forwarded-Encrypted: i=1; AJvYcCVcp2ESY7EZ3+4D9K3Fp7IXY79+M8QbRytPx/JWI0iSNbBrEC2J7HVElx2rhaXQRuZLrNKrE1K+QUmnHOc=@vger.kernel.org X-Gm-Message-State: AOJu0YzsbFHOjyevUl0kzkMjDLEl0ruDY93iqWXT7Qbe8FwMbnWDtzk5 7h6Hdl1NEumzRfswoBJavOfpgCH4jhSugO+RC+EgUV5pCwKS0cOvJmub X-Gm-Gg: AZuq6aJQpqf2lGTfP9gWx96UArS+lcr1+kJl0FNW5HE/MCr0Ya9E0tX/1YMtmMdPWVU vn2ysDrov5sFaxltX12BmfiKZKkKme0U5v2LvDrqchegEecKw7mCyqBdVJTYLZRJnFGKFt2Gk5Y tpyhExQsChXEgDW1dI4yi6mQTqa2BYlFG6zlDzIIil2wSPTsObpgmbF1dQQDIjAju83KLRcdVN3 N25rZwTcxCcnU/zKqttMotXHtIne/OnrPaaGagmwyyKp6LXDKmHHq3rlxF33WnUgtEdUF4/am72 7Z3FAOA1GjpCw6Cuwvo1jtrq8noRi3rzZ7wvy5ArjXNb3HZe/0fqGfUpD21nH6+PJf4X/VL40uQ 2++N6qpdELZ6REzqH7hmvKqwx82eQIZISmhCznYBq21JSOpEMx7iPrcWSo47DjpniT7lKSswp5G 05zI2fA/09r7/bEnbvk8ec38Q04dnJRBhImH03mIWb6rmYl1OydEweeuu/DviJLY+hBUee7Zi4q jU= X-Received: by 2002:a05:7022:24a1:b0:121:d898:edae with SMTP id a92af1059eb24-1276abe9cacmr3849560c88.24.1771907528435; Mon, 23 Feb 2026 20:32:08 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1276af7b4c7sm9607887c88.9.2026.02.23.20.32.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Feb 2026 20:32:08 -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 v3 2/6] platform/x86: lenovo-wmi-other: Limit adding attributes to supported devices Date: Tue, 24 Feb 2026 04:31:56 +0000 Message-ID: <20260224043200.2680384-3-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260224043200.2680384-1-derekjohn.clark@gmail.com> References: <20260224043200.2680384-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. Reviewed-by: Mark Pearson 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: Rong Zhang --- 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 95886df39c8d..f3f12303e379 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 Sun Apr 5 19:41:55 2026 Received: from mail-dl1-f43.google.com (mail-dl1-f43.google.com [74.125.82.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 0C23B279DA2 for ; Tue, 24 Feb 2026 04:32:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907531; cv=none; b=VlcxOFpY5P/879qSvH7CTNPVAiQ+XBB3FT7Eq7X0R3L11D5sok0vICTdH4D6Ix9a4xdlMclwPUcNPzDRSrc8ZyIx37oy/eW0a9UO5/trTgZ8x8auTEf2+dS+Fd/PSnIeiykjNs0vdrfdXfQtFGlvx0n7D52+y/MdBV7/94ryR40= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907531; c=relaxed/simple; bh=sIRzUN3xyF8YtANkJcMMtcYfXNg0uYu+T1sypey/XpI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lCpT8tSk8L0qqy0EYGPLVJrgRoEucgm6vk+16UV9aZeYPC8idw9U7KuiKTNCCjL3mVXfLR4Tb2B6EYCTEEYJuSKIaQJlFiL+XSTJ6QZkmnKo5O6deRRGknxUwRMZD1RtGYaTUOQb5vb/BHNoaWZi0BOoYLSsa3BuO6QV09wloIA= 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=ev0y2DNX; arc=none smtp.client-ip=74.125.82.43 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="ev0y2DNX" Received: by mail-dl1-f43.google.com with SMTP id a92af1059eb24-12758ce1e8dso567260c88.0 for ; Mon, 23 Feb 2026 20:32:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771907529; x=1772512329; 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=56CUuBs5aoxiv/DRtlg7n68+hk29R+WL0IJm73lGTYs=; b=ev0y2DNX74SJ1qL7rDq2/DGjt+BLx3hBOXLUPS/paOjhN30G5jv4m4GAevjtpV7R+P ut9H9gYx99ehsboU7l5QaF3YSmNttLy/pE2efd2o5izHx096FtCUtNYNsYw0pR3NSUos eYz13PgDahVHSydNNjAs1lf0DqR+VKRs2jJ0IomQ0yocMjtE+Jvk2BFT7rZ4MSJlmCCB 5kNzXTAeopW/3vInCoE70NkpPY7S62VUGIqqPAp/yL+JVl3rXYW5J6H3DP1UTJTMlt6u VT6jxwqZDRKgvZek2TQyJoAsmTq8YCpzwCDAHIL14lmgkB2Am1nL2+lNRXm22TLG7NvG IlxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771907529; x=1772512329; 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=56CUuBs5aoxiv/DRtlg7n68+hk29R+WL0IJm73lGTYs=; b=qqncbZRuw7Tikll0xSrYieuogNLTUY4HPzo4QN9uTV7wP8fLP+BHZvMO1uhPe8usT7 pFMnzcfn7LHCuPouIGOAg+fK5olJNfhasIAkiLAjagu8r4hGqZ6K3Cvoe6IKBHLBhu3c qegSShGt3isycpBqB9+RtYR3Acvi75dZ5IlSZ/wBcD6YEdipKpm9lp6Yn3qsXqqt59c3 HCgvtPWzfSXKk085C03bJ3W1PWRxNx3EoKYBHGBPVranter0adQprWgbL86jqnP/ZYgF wOGP7X8neE8IQX0fJs9dXMU18wmbM4c2ZgGPGZUdrTJdoGefdLXnE8Ij75Aq6S5hQ3sU pMVQ== X-Forwarded-Encrypted: i=1; AJvYcCXI97zLA6LivnO+EokPk1Rf6gIiFnYnKmrSYyHObc77azhNx8ZnYk1k6oi6a7MSg4QcT4un6sSw0HXfQK4=@vger.kernel.org X-Gm-Message-State: AOJu0YwhcqCFx4qnHSYRK36cex+BBkjVZX+bKwBQOjLTKyLPfeo180bQ WvhDrvv/d/IgneE6apNPgYxxnnQLWDkRwHOvDiqiF/E9+08XAJd5qpSK X-Gm-Gg: AZuq6aKAGapbEXQPbrxfHVVTmbMp2CA/ZmAU6R4jaweNF26iQwBUQBXFalGCG2yisyj pHDzLKu4so5VaznPv4PMWj1O+xD2345h8u9AkrXP7vm7JGaMhaRElLVkijL/Lca+rdFsT4wFos/ fUgEmX22O8vbLpnGkjSwz61aLB9l0BbNmlUJaM+VjhO+jGtbjw5+hfGuTql5j3swY0Ia60U4QuZ S0GBSMMXw1fe/qRzzxzOTfnypBXa+8g2hE+VKzj+uXZ9bSkGsTd8zbf9YuNJ1ZTRCtI3IS2/HzM JSTSMFhXiulbEqI1hmruwVGm3f1IPdBsJvWT+E5O7iioHJfn1I1fOI0wJ1d24EA6mfupYBps2bk xRId7q9jsFA/Kp47kz0fGvlEjIjcHsYtXwQ7SUvwi1ATrmg7oOUOA7MCthp3s/Cxd/o5c2AhztN gsgT3/H2BE52Ofy22+Gw9kJQKyQBD6PLT9nPm+R9SDNEX6QLZTEL1Vq/po4n7gyDApCZHIsTW+f 8c= X-Received: by 2002:a05:7022:1e05:b0:124:9acd:3b15 with SMTP id a92af1059eb24-1276ad81bd6mr4856346c88.39.1771907529079; Mon, 23 Feb 2026 20:32:09 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1276af7b4c7sm9607887c88.9.2026.02.23.20.32.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Feb 2026 20:32:08 -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 v3 3/6] platform/x86: lenovo-wmi-other: Add missing CPU tunable attributes Date: Tue, 24 Feb 2026 04:31:57 +0000 Message-ID: <20260224043200.2680384-4-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260224043200.2680384-1-derekjohn.clark@gmail.com> References: <20260224043200.2680384-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 device ID's and CPU attribute feature ID's, add missing CPU attributes. Reviewed-by: Mark Pearson Signed-off-by: Derek J. Clark Reviewed-By: Rong Zhang --- .../wmi/devices/lenovo-wmi-other.rst | 10 ++ drivers/platform/x86/lenovo/wmi-capdata.h | 5 +- drivers/platform/x86/lenovo/wmi-other.c | 98 ++++++++++++++++++- 3 files changed, 107 insertions(+), 6 deletions(-) diff --git a/Documentation/wmi/devices/lenovo-wmi-other.rst b/Documentation= /wmi/devices/lenovo-wmi-other.rst index 01d471156738..f4763ed66cc6 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 27202e2dc8a5..aa48f43cbb43 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 f3f12303e379..87aba244da84 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -54,15 +54,21 @@ =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_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 +565,72 @@ 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 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 +1069,45 @@ 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_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_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 Sun Apr 5 19:41:55 2026 Received: from mail-dl1-f50.google.com (mail-dl1-f50.google.com [74.125.82.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 8490D27CB35 for ; Tue, 24 Feb 2026 04:32:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907532; cv=none; b=lXVWphdoIdtzOENDLRT/LaFqlp3LMWnFPHF5XU/QkJ+f9um6BkThPTc81WBfQ9gYSi4ciisZ43ElCu2uaaGfZXNNpFX4v2mKOh4doWPfbLAxrEukf1cVUqS5IroGY1nltqLalNKheKGsgOcbOT1BRHFS+ATggrk29uhxRRW0YbM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907532; c=relaxed/simple; bh=nEkPRkLVQRHHUQm1Vvmpv+kKOYwKxIhi1fJkMphZTdM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lzZh4uuQgNlCrv6NQQVcnNJQCJ1Ic5n76xwji6dH0T49Fn2H+iFX76ZdVQE6cOlo6d4oEqq8zflBn83jxhbHd7ZgjDILp8kBLRoth1xSVyImZEGVxoiYIwSpNjJ6fMHz4Y30c4ZT35uwL2QF41WRbOpvT3CSU/2olLbekHL+Cm4= 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=cy0MA9fJ; arc=none smtp.client-ip=74.125.82.50 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="cy0MA9fJ" Received: by mail-dl1-f50.google.com with SMTP id a92af1059eb24-124a635476fso4763385c88.0 for ; Mon, 23 Feb 2026 20:32:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771907530; x=1772512330; 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=lW0PTJ2xSTHIHILISSH+wlmCW38PDwPsaAVhAgtz/fQ=; b=cy0MA9fJcPeIMC0t9WC84uxf35I7d0LBdYj47KCH3LPtpcaJrFUp+abNTJiBgUGuW0 bahrP/DiW53ujUviOJmmFYcQMOAy8iGZ07yUMWBUEbMFTg95zGvEeIoJ5XtwjKbPoUff AjULip7RayIiYAzNnpnXkFYfLBosxB8udYKJ+HXw5vIRU/4n39vD9iyhQET8QIXrjAXZ fHxkfbsO3zLz7PeAnrwrwKj3oPya7MpG28H6++4qIlWpbfU1pGvoh1hNT9hwgOL+F2RJ e+rtvr+5rnrU2uP2Mz6Qajst2zkNQvdnLGIo3zyGLcjB7GUWnE9EIb0lO8c0iEE2kq0u 9P0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771907530; x=1772512330; 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=lW0PTJ2xSTHIHILISSH+wlmCW38PDwPsaAVhAgtz/fQ=; b=ATnYwQ+oaEAQAzpTc+mo2mExgVeOCNDMDQviu1i7h7gwhBcPfHg6LlRsLM0yAzns2q zteyspGySymIAJvsdLO9P9+EZRr+MfP6F8sbkOWlUDQdLMNSxxjf1p4AkWpdq75ve9N/ j+0mBSYvqt2IOrRnKAQGszT6XbCWpDyxWOIa2rKOcZ/6cW+kaRphc3L2MBC5WU0aTrE3 N61w3DhNMe75s2ar1c9vDHWKFdnTDlpSIVEkGbEXo+58iWGjg2gmmtsy0rQf5Oi3mRiG 7nzj+und+AX/ouEQFxETXOg1iVvpP6X40e+KiURAsyIOKsHW3E7LSwAXCcDh6MZQasDn LuMQ== X-Forwarded-Encrypted: i=1; AJvYcCXAxSfB+e72f5VTBtS78g1+Bj/sBxbozRM/eDDVj255xGqPicL1lxR+t3LzQsan8A41Oua6EpHd2QiRg5w=@vger.kernel.org X-Gm-Message-State: AOJu0YxcklpaSTuyf9uv1bXBB4qj798vbVYJGmhihcKGVssEMJSTzhtS njuzQMeU+Xn2Q+yxYjkyS9wha07Pqp8NAAVcsCYW7U9pFG9H2fK4H+FN X-Gm-Gg: AZuq6aKLtpbQN2EIOk+DTSm4cbFW7cXGHv+4Vs+Srjg6BiQa0I+4GyFu0ZGF2yYFiIz YvH5l0KzW68NYlUysT7FnNwD/DPSNFWlvznKx7X//8rUtZavjLabURDx4mefyIlnLsBOZVBB051 LLLaj+SOS5Ezr7wpIOdBs7No8DzhaG6EyO9sZtQ35bMMmlX45Cx7vFDICxIO7fDRJi+RFeFAAeO WU5utDD48NT0kkYOGe0xZY18t5y9zSXAkTm67c6HoJDHZ4VtV5GjYg3Om6s6ibzOS+dvj+tBz5f cCEAThC3J8/no5DhWFaY7OvWgFr1zd+ppPIGizAEX1Lat9d8AR755PHG/mjNcq4gTMQAgxGFMxu 119WI6NrTeDmjwYYnkB2TwPR/i/EZOj9iqHBjrIhvilq/G0ReYVEq/WelyDH1YMjobuzYcxbtpq zG2Kjo7sp+vmpo3ur1/t/fpWIPHhUlJigzOptlzaabfKEvuwl8Fd3rZNicHiWTzDV4eigM38Anl oI= X-Received: by 2002:a05:7022:6b93:b0:122:33e:6d41 with SMTP id a92af1059eb24-1276ad11a3fmr3001986c88.23.1771907529704; Mon, 23 Feb 2026 20:32:09 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1276af7b4c7sm9607887c88.9.2026.02.23.20.32.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Feb 2026 20:32:09 -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 v3 4/6] platform/x86: lenovo-wmi-other: Add GPU tunable attributes Date: Tue, 24 Feb 2026 04:31:58 +0000 Message-ID: <20260224043200.2680384-5-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260224043200.2680384-1-derekjohn.clark@gmail.com> References: <20260224043200.2680384-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. Reviewed-by: Mark Pearson Signed-off-by: Derek J. Clark Reviewed-By: Rong Zhang --- .../wmi/devices/lenovo-wmi-other.rst | 11 ++ drivers/platform/x86/lenovo/wmi-capdata.h | 1 + drivers/platform/x86/lenovo/wmi-other.c | 105 ++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/Documentation/wmi/devices/lenovo-wmi-other.rst b/Documentation= /wmi/devices/lenovo-wmi-other.rst index f4763ed66cc6..f7564b23bb7f 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 aa48f43cbb43..b7f9ee7b301a 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 87aba244da84..67768f6a50e0 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -65,6 +65,19 @@ 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_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 @@ -631,6 +644,66 @@ 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 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; @@ -1069,6 +1142,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_temp, "cpu_temp", "Set the CPU thermal load limit"); LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_cpu_cl, "ppt_cpu_cl", @@ -1094,9 +1168,40 @@ 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_temp, "gpu_temp", + "Set the GPU thermal load limit"); =20 static struct capdata01_attr_group cd01_attr_groups[] =3D { { &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_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 Sun Apr 5 19:41:55 2026 Received: from mail-dl1-f48.google.com (mail-dl1-f48.google.com [74.125.82.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 50496280CE0 for ; Tue, 24 Feb 2026 04:32:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907533; cv=none; b=beKcbOKwEBBypF3y3ekndg7Mj07WHvtdZGrG63iwoBJrDzqK9VYdaSKRFdskiRRI9U8glvIA20+ZwLGvPpvydHTU2KAN85N1NhqsYJIpgQZSZR+zc2d141bsoRg0/zONsbg/VfFbOWCikfODnNVltRhq1iiSQ07GExNNZhzF8EU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907533; c=relaxed/simple; bh=BSX/lkKlpLye9IVPETat8Vg/SLzeUnyZtBpISqsdFPw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qKzuoqBuMxXC2SPSTSUhG5Q58iVJicUE4KxUyUPGMSlesW2UePijv2wMUjQjnL6x6B7k3i3JCPs1WF/aaR3No6kxnsq+VMy4W9sJLbj0WRqlA9YnIlZQCrti9wRjHjR7zEItwz/dF+WR4aTKG8FI8k/7Ti17Bc/a2oq4LJ/kuNE= 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=L3RuN6q8; arc=none smtp.client-ip=74.125.82.48 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="L3RuN6q8" Received: by mail-dl1-f48.google.com with SMTP id a92af1059eb24-126ea4b77adso6117868c88.1 for ; Mon, 23 Feb 2026 20:32:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771907530; x=1772512330; 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=yUGs0gBmWbDnzbyUxiLzU5cMCH5VPbW0yPuDJsteHR4=; b=L3RuN6q8updHyd1zaElSDPyKati6lxCVY1sk6+IU0WHzWl56GdfKWZEQGiRnHgE8m7 3FqVdAAeSlyMVhIAZnC/retNXfxPwq0fpCyhEFnLaUaTNNQSSyd8LbEl5VIxTcy+Zpro t142kFaT1pEiql48fDrwwsd4rKKM5oAd80iNHf70Z0YAscydKHD8fPDvWcb3sab3BE7f qE/wv/HhCnxNY4+nu/ON6BKE8TUAwJ3oBwRRy39uAFWLzyURKS6QJ8OuD88UUVIne5b4 QU3SjWD3onYob1NWfGehwUq7n15k9Kyf5TQ4f+ISVvyV4fdTMWcF1B/Yzodew3ynU0UX kYiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771907530; x=1772512330; 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=yUGs0gBmWbDnzbyUxiLzU5cMCH5VPbW0yPuDJsteHR4=; b=Ts5lxM0IgSl+IQNOMr4JOE4taYSO4cdFcPQEP+DgnLbGXQISUP12F8X8HmiMINbr1w tHyyp7sXLUvMvDQOadwn+ux03Gv9Y70h792Ns2RHQl2OzsixbnkxSegBFmFASaYI0xX2 lZGZzLS23Syp6HAxy1Qn+XnzKNcyRJvwj7Wk9M6shfq6P69a1yoYhylSk7yvRckZ3AyM rn8w+wulmHu1ghdIljcZj6oPFWI2PmbEa5GH8erTytsh+9FvugiDSYmC05gsKGjeASK4 XhClMyv4jfs7iaylu13fVSwCl+yxOeM5fdfmV6rIO826yxkr93MKGiosKM5Z32K3SiUh AUuQ== X-Forwarded-Encrypted: i=1; AJvYcCWsVclFHVsmzALLrtkjrL7p+IljHizYLYtoBkyVeCA3ubIg0DIMtj3leyAqWIYqKJWfhl8BGW/2WjPAm9U=@vger.kernel.org X-Gm-Message-State: AOJu0YwjX3QK+zwEekcs3//1lTqRWWb30s/aW1Xhg/KfU2lLZn5iKK/H oAz1PZMYklTSIyWBRFvzT6VwK0NE7uHTbKtchCdTuJMAHaDSLNCF6D7O X-Gm-Gg: AZuq6aJYYo2/Icf1EsogmD2jaruqfc0LE27byiaxv3N80Gn73gIlyjhQVx96o/D2CWG gSVSUjhXi5+PfAVn7mG4ugGD0aP76Q5MBD/lNC0Rl2cBpnmcG+Dy0b6hDI+CdXs2J3Gt7e83Auw uAhiWzFb/v1fbcWRU+poJn4nX3C2flzNgVr+jkwFn8XmfYppF9VC43nP3vbyL8fot2hfWkbmeEj N9d6bPKuGh3oMUWqwGFa1G9W6ZZKTOBFPQBq8wMtTRRYC/88L+mC5KQqGPOOhDcyq81VsSrDMUG J/BUb5ANPCs7DMairmIY+TYkZxI3+0jpcwdyFlvRevRuM+YIzpFdjXdICW+OEMu+23MBvULDmrw MvvYKl08Qg9jtEapcAayWnSQxgyAelSxPEdIbRD/uvPLbjp/stpPo0pocDpVJXtsPcQCZzg/ECd yZUabhyugJKO8boQdcYDL8cE9mSvJhvWgeY400K8YiEtZ3rKVZvD6Buc0x2ASEYzueFvVs/ZrEw vY= X-Received: by 2002:a05:7022:248b:b0:11a:126f:ee78 with SMTP id a92af1059eb24-1276ad33741mr4628325c88.34.1771907530284; Mon, 23 Feb 2026 20:32:10 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1276af7b4c7sm9607887c88.9.2026.02.23.20.32.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Feb 2026 20:32:10 -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 v3 5/6] platform-x86: lenovo-wmi-other: Rename LWMI_OM_FW_ATTR_BASE_PATH Date: Tue, 24 Feb 2026 04:31:59 +0000 Message-ID: <20260224043200.2680384-6-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260224043200.2680384-1-derekjohn.clark@gmail.com> References: <20260224043200.2680384-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 another const macro with the same information, replace LWMI_OM_FW_ATTR_BASE_PATH with LWMI_OM_NAME and use that for firmware attributes and power supply extension. Reviewed-by: Mark Pearson Signed-off-by: Derek J. Clark Reviewed-By: Rong Zhang --- drivers/platform/x86/lenovo/wmi-other.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index 67768f6a50e0..7f0d5a17b44f 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -90,13 +90,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_SYSFS_NAME "lenovo-wmi-other" #define LWMI_OM_HWMON_NAME "lenovo_wmi_other" =20 static BLOCKING_NOTIFIER_HEAD(om_chain_head); @@ -1233,8 +1233,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_SYSFS_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 Sun Apr 5 19:41:55 2026 Received: from mail-dl1-f52.google.com (mail-dl1-f52.google.com [74.125.82.52]) (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 ADC262836A6 for ; Tue, 24 Feb 2026 04:32:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907533; cv=none; b=g4g8prTvq5Zlmlshr9o8eA2c6ut0YTIba6s+OJA0G8GIjMTzg9Z0HIqMIlZ5LKNWc2rLjMhY8bw4N95zMmy1d6NmUVHsTh8F40GpTOX0+1bMPruaAksEEF9g1s46zUir1/pSIrbzIgxLaKUlmqAHDMtusrpccaZh6KN44GQdJNU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771907533; c=relaxed/simple; bh=kessVQ8OOCDF+bsFY6W3zPIUXmUylLTWeH7nV4KNA9Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GIivO7+PZDX3n4B24lr85J2eV2/i0Z5Iz4OyrtJVfXZJu1YehlqNMYYBL+9zLvIrZBmkjBZCJ08FRugXnVZx+qdTX+wbTVNMWxBcdhcdyfHxFqZ0il7uKjKs+3w61NTlk8JbRqpsM/hLzAaJRpdEx3evk0d5A+9x/tRtDjZqqf8= 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=V4tYjiiX; arc=none smtp.client-ip=74.125.82.52 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="V4tYjiiX" Received: by mail-dl1-f52.google.com with SMTP id a92af1059eb24-127423bea4bso34537c88.0 for ; Mon, 23 Feb 2026 20:32:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771907531; x=1772512331; 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=Ilbe388Cxt5TpkwJ0RJZDtRFNc1WD3dk5cFWqwGlj9g=; b=V4tYjiiXIgillW77OZvVqxaJmARcT1j+Ccm/jdJ3eBITOGIXSl8fWkm0qPC9B5Pjkb i62l69WJw5OYE6ijS6I9+4/2zTkAh8PqGHhVSC3z8IhT9z3v2y2zk7oJddq6SEJ0uGaU UOVTJlPM/AtMZuPI9qIJm6il2DZGaS2MoaP38HR+Vd1UO5aZIdiMYq8CclEFVlxPaRGg MWWkG9nFlPmd9DNFfZ397ppPtd0FzYtBxtXPfBc95zshlC32yx8MNLYjvRCp1vCV+Ss+ c2k/rO8T8xe1h84htBcu5aJ/TLhqHFX32B9aHakfpUPNG/fKd4MfZJWIWM3JGop25nIQ hmqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771907531; x=1772512331; 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=Ilbe388Cxt5TpkwJ0RJZDtRFNc1WD3dk5cFWqwGlj9g=; b=D1dx66mwcCbahTz6HyOfmvlGsKGgTvggv+zKTm/aPE20Iq17mNovo35CGZU6Vkww+B 7qewgAdwkDee0PZHgl+I0lbsvd6rvwLaiq/Z6z0X5dXbUImtk9xqVLeNedAzPwF9EguT 2Gj8RrVddYcfhboLBnhr8f/pkpzirZTZ00yqRYDD6hs+Gst3uGQ2B9Oe/OR1orjPk4f0 fIHmyCBDi5BCKJSghc6ZvZZ/zrwly2jzlMn6a7Tkt0ue6ATEAcFUTSbJwwsjbokpMJU8 v5yeWttD+jceuoClmcYmk9tVtWA5/DFzIrpx04JNElhc1h4p1acOmSU9xS61U7hS4pYq FcyA== X-Forwarded-Encrypted: i=1; AJvYcCUfQMD/nkzB7Nk5ZBX+a4AmKPPhGbDYndGgo6HjDYZQKkPXOSXFnx8vSK+k1bt2GnUOof0DQMiBy/IWisg=@vger.kernel.org X-Gm-Message-State: AOJu0YwZlG3sThnUH+p7te6IkPmd66jay5LB67NsNKSSpaLPrYjPUfwb z9HFqWfVKdc8JoxawUuuh8GuDH2sWX9Uveu3mJ7DP7m0w5u0VSdID8+Z X-Gm-Gg: AZuq6aIOFOE6xsUF+xKNZVGIwfrjTham6nyJX+JrYaQYZWkREbWXfXj3yUzWYjuRbYY WZvV9boMJobqM/V2dElkoUcnbJgV3FNSm+f6IrgMHEL7VNz3H+h+/abMnWYk/AQAplaN/5O4L3T nTr3y5jmjHgDeEdDTMdARwCQql1aPN6iwQbth6aR83DOfWCvzjQJjehjBqzO27xcyHx8Qbh8tEa 29edTlY2hSdW4nXQ5OroRfn/dIm0fjIQ+ytSZJEFKFdfMMuimclqlDMDt++BDwheSr6IZkvGaOp 1kNFqWHUo2FZ4wG95U8qxPDERiX1fcZcQjVvcjEctDf/k6eeFRA9WpT8TF/sFYKZVeclCQYAimb bFmVrYlHE1rct0SO7nGMh48O8PnqyU/GVyWYOU0Nx+xswP5Q1hLO15tE2DW11EJ7/ygU2A3EJoJ X+GJARhTQIxV5uL3sooNc/Aph4z+noIoZkPef9HVNpLgI+xjXl84ABPI9Wktf9R3VtIQEes0wJI tU= X-Received: by 2002:a05:7022:685:b0:127:33e0:ea33 with SMTP id a92af1059eb24-1276ad11e4amr4942976c88.22.1771907530905; Mon, 23 Feb 2026 20:32:10 -0800 (PST) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1276af7b4c7sm9607887c88.9.2026.02.23.20.32.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Feb 2026 20:32:10 -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 v3 6/6] platform/x86: lenovo-wmi-other: Add WMI battery charge limiting. Date: Tue, 24 Feb 2026 04:32:00 +0000 Message-ID: <20260224043200.2680384-7-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260224043200.2680384-1-derekjohn.clark@gmail.com> References: <20260224043200.2680384-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. Reviewed-by: Mark Pearson Signed-off-by: Derek J. Clark Reviewed-By: Rong Zhang --- drivers/platform/x86/lenovo/wmi-capdata.h | 1 + drivers/platform/x86/lenovo/wmi-other.c | 230 ++++++++++++++++++++++ 2 files changed, 231 insertions(+) diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x= 86/lenovo/wmi-capdata.h index b7f9ee7b301a..00471551e7d6 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 7f0d5a17b44f..b2daff1b45c2 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -42,9 +42,12 @@ #include #include #include +#include #include #include =20 +#include + #include "wmi-capdata.h" #include "wmi-events.h" #include "wmi-gamezone.h" @@ -78,10 +81,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 @@ -92,10 +102,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_SYSFS_NAME "lenovo-wmi-other" #define LWMI_OM_HWMON_NAME "lenovo_wmi_other" =20 @@ -137,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 /* @@ -561,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_SYSFS_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 { @@ -1325,6 +1554,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