From nobody Mon May 25 01:14:34 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 1B1B1367B83 for ; Wed, 20 May 2026 06:07:46 +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=1779257267; cv=none; b=NcKvggniUdJcGxI/h7woKRax+0EVy/m+ofZ4qCP+a138gsKa0zjGeGrWL2+y6BH42kpl+opbARUGzbptTL7dsFfHCTsLT1qiiSll/kRpv5wovO129CQ3dgnVAMCZaQNA2yniKIkoEkDEGhOP75lcC7dilSGJMKBtVF0Lhx2saMU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257267; c=relaxed/simple; bh=cvBWj2KS0C5CFGM8Pwuf+eDapN5TbgqVM/JSY1erLUw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FUh4XIncksi4hJkx90UtKMdZtNq30pylDETIYZyAjVCfc+pPfsugq11nQN4F0I080YaVgAUeeV7PxMIcp47BS2ZahXnGcKkJX45Vm03gA7wZgdcAf/s1FS417cWbtVvSWaeouyxtF6iakIg/Vrl78/NtNX/D3G6FtRBSfcULRZI= 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=CR1AW31r; 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="CR1AW31r" Received: by mail-dl1-f43.google.com with SMTP id a92af1059eb24-135e88b8e55so2026818c88.0 for ; Tue, 19 May 2026 23:07:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779257265; x=1779862065; 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=RasGlteF+K33aN/SbpNWfGwT+9lCHJ5HMQsoJjlLjcs=; b=CR1AW31r2EDO1rhk10nL4uOjKOt8B2+PKHMk414HcUo9DbEdk6G23S4qfoTvN4EGXp 5CxCzP6HjmU0AIioqyT85QX32aqJvoYWXVBuMwbUbIlefPhulYn3z83MUewTeanN42HU Fe1Do9bn8ktSD/x0M4gK0+OcNEEH42MHizOrc3JLGC8lph6qDKioYy8OKXCWScw7WI7Y Fok6zeZg+FNrEhg//PJvgGrRNh7TUbmxavg+g+XvbH5+HJ4Tfu047IcRpmp3aVsTZg4M I5yk1MZxGAaROT51phif95UGeaQie7kL5cZe+JOfT6F9y6vqg3xB8CavvYYKbHfbyRkl m2qQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779257265; x=1779862065; 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=RasGlteF+K33aN/SbpNWfGwT+9lCHJ5HMQsoJjlLjcs=; b=VWH5cuHrrWvW203xAEiP2fYD2lq/4cKjWFXgbg1rlugaD8ZCJG1ocoFgsMi7LS2oPY T+dUIJ+T1tKUO0bzwJusbIVxxLSCyxLrMSgs7ujtbAw4Wr1NFprVqkfEfOxJDxF6u9eI Pr5E5KJgCJeS/Mm3Sz6xzbrtzhPXKBNiL4monVjdHr3pk//C5HZ2spJy+CQNnYbveAk+ 8WChcqQNx9Fc+N4HVV1RRf62N7HqrsWb345+7xmn799HIe79MSHAMSq33aIw9vG2EvzC gpfjm6I0+LGzF97rwHukpafhHU2rI8f0+2t4fkt3GeEXe1MtfjoIbRQQOUplx0KaI9IR Vdmw== X-Forwarded-Encrypted: i=1; AFNElJ+Iw5gt6X4JihLcccxO2G7JnCZe9Vsb8WAd+3BcEDciQm7o4M6JI0tYN6c7sAUdXgomR49n1qcMSUsX9D0=@vger.kernel.org X-Gm-Message-State: AOJu0YwnikI/jt0Jj2hRhvu3izXQ5jVbzogH/pN1+0Vd1D05OnoZdTgD 76O+c8ZODbb53WlWEZoeNnJ2/P2gAW7dUb7ZD5AT07bTO27tTlGkBuCQ X-Gm-Gg: Acq92OGfeSq1rUQXL67xsQJnEfWSPz1kR6px9hkkrHi1J35+zAJatH/pYr+OOkDkFaH FO2Ltp+EgxowWgkx6AU2eVybABoH52xD9F2OI+tSEjDNI2afZ9mN3qjC5y9sNhSdrjZx9fIsmuk N/gbZKq4JodOt5tB6dG+OnApseoSRvPox4vxPMaldwKEjqPWGhV91L0VrIkOrjJXbBqLIzwK61u cTusSDBRJFbb+GLBzFIZNaWGDXdiM/2bFKWhdwtnfc2po282C4+zv9kFb09KtnUxcWJ/kGkQZKE 5t7kedUIcvX3i+yCAFTBjtX2SuYOytKZ4ELofNVhf0hMHNsafYZHn5De/wFsnp6CWJ1ml0V8Yyu xd68teAiszDkmkcBn1ydMPdcARAATNt1YWy73KnqQyNFviP2fEKz6vXINHuiJ7F2ZEUJTg6AMsK Q8GWExFxoYIc+HwfzRI9r6yURuWAM2UuzHRDyOA0CS8jdpfXyM2mlfksybrwe7rN/Szk81+pJVK PAA X-Received: by 2002:a05:7022:4187:b0:134:7497:2148 with SMTP id a92af1059eb24-1350552c4fbmr12226332c88.28.1779257265172; Tue, 19 May 2026 23:07:45 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-134cc2351c3sm27906026c88.11.2026.05.19.23.07.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2026 23:07:44 -0700 (PDT) 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" , "Pierre-Loup A . Griffais" , =?UTF-8?q?N=C3=ADcolas=20F=20=2E=20R=20=2E=20A=20=2E=20Prado?= , marshall@shzj.cc, hyacinth@shzj.cc, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v14 1/7] platform/x86: lenovo-wmi-other: Add missing CPU tunable attributes Date: Wed, 20 May 2026 06:07:34 +0000 Message-ID: <20260520060740.119554-2-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520060740.119554-1-derekjohn.clark@gmail.com> References: <20260520060740.119554-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. Reviewed-by: Rong Zhang Reviewed-by: Mark Pearson Signed-off-by: Derek J. Clark --- v7: - Fix typo in documentation. v4: - Align type ID defines. - Align CPU feature enum values. - remove cpu_oc_stat from Documentation. v3: - Remove cpu_oc_stat. --- .../wmi/devices/lenovo-wmi-other.rst | 9 ++ drivers/platform/x86/lenovo/wmi-capdata.h | 5 +- drivers/platform/x86/lenovo/wmi-other.c | 99 ++++++++++++++++++- 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 01d4711567380..189dd4d31926d 100644 --- a/Documentation/wmi/devices/lenovo-wmi-other.rst +++ b/Documentation/wmi/devices/lenovo-wmi-other.rst @@ -68,9 +68,18 @@ Each attribute has the following properties: - type =20 The following firmware-attributes are implemented: + - 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 Tracking 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 c3e760b8c3c3d..c74a0e5294e78 100644 --- a/drivers/platform/x86/lenovo/wmi-capdata.h +++ b/drivers/platform/x86/lenovo/wmi-capdata.h @@ -18,7 +18,10 @@ #define LWMI_ATTR_MODE_ID_MASK GENMASK(15, 8) #define LWMI_ATTR_TYPE_ID_MASK GENMASK(7, 0) =20 -#define LWMI_DEVICE_ID_FAN 0x04 +enum lwmi_device_id { + LWMI_DEVICE_ID_CPU =3D 0x01, + LWMI_DEVICE_ID_FAN =3D 0x04, +}; =20 #define LWMI_TYPE_ID_NONE 0x00 =20 diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index d318ba432fdcc..fe4cd7da017eb 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -51,14 +51,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_CROSSLOAD 0x01 + #define LWMI_FEATURE_VALUE_GET 17 #define LWMI_FEATURE_VALUE_SET 18 =20 @@ -566,18 +573,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; @@ -913,17 +974,45 @@ static bool 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.53.0 From nobody Mon May 25 01:14:34 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 A745A371D10 for ; Wed, 20 May 2026 06:07:47 +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=1779257269; cv=none; b=Rmgd/BL3eBpyliwZfmp4drE2qdImvYebIAi7Z816Iwyl12M7VaUx5+8TttzebVxCM+kFEvbwFnkfh5i8nBYxqv+7v+7KSs9VbKkesIt5nBsDnykzXwCvmzOk/iyo1kSOdHBjBCG/nZPxjSY3gKvQBeWEkjVEev5vFPApMg1O6j8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257269; c=relaxed/simple; bh=+vYi9Orjk1zvxoyh4C8l6PMWgK25P4gVT8jIhytANdw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=deh6v4fpbBrp+i3N+RhUrvCY9KbLmonK0+zl7dq6LXn1a7Q5HsrYmbp+VL1hiIjwdLoQfFFZROnF1sVLypL8Et5w9avnD6BoOjcPMf7c0KblkZTQXqoTUiOsGsB2Do1C7xG/u5JReovquR6GPz6zbLhz/HRNl6g9ypcwT579VqY= 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=sYIR1UA1; 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="sYIR1UA1" Received: by mail-dl1-f52.google.com with SMTP id a92af1059eb24-1353c2f35cfso14673691c88.1 for ; Tue, 19 May 2026 23:07:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779257267; x=1779862067; 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=8X36h0NgcF0aKUOU3c48+jC+jUVz0rrsqnrUzQjuSSY=; b=sYIR1UA19HqGY2Z94WdiN7rtZFFGGF3lChMCln2nEVyQh8qtowbp+jvYI2UXyYhS2+ lrMPUZFM4TRVu8PSCCGlCRghwEBoRu+KQKnCHePN/nBxBdaELvDvU8jhD0yn+rQ3sGF9 +ODPsf7ZmtSw1OKVrKTVbZYj43SXR4G8BzfNRZE+uKTJKVTH/aKhZn5cvf1P9zK611pV /8x9sYQxiL4fKyKVZspa7MONGo1DMFUQQzt4srzHdgseo1dkGoky9QThIC8L0hqe0UCv RZQ0qDo2d/cG11XWXH/5pXHse0wuEGm8BfLGR7CL+1Hw8p/+dutHrHJSQXRfpx3xMBT4 lQGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779257267; x=1779862067; 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=8X36h0NgcF0aKUOU3c48+jC+jUVz0rrsqnrUzQjuSSY=; b=SyYL9pyNY+02W7vOJEBWf5jgoYQhd/jSQxxHMxmLzv4JWTEls/lWGyaaaDu8Oa0gbM QKtRYCfI8oxRYNyoL9L2VCNfJoTo1W2ftDU6KsfZE8q5j6PYjw/srjg3P7kojNtqoUVz LSsMIdbDnzUy7UmpeS+nJrFUwWSTij0H0M2u9RBmuntdYE2tTUuyIwLacq+RH60D7oIm 6R5koptAYhFkENcd1zoJJSZeL6Pim00/kheixiZaDDx21zPU1E2/9MGYMlHob/Fdyob1 D6OAe4V6Yu/5/p4inzOsK2xs4mt9g3Cu1i6aRAlQmeade7zJs+ZfADRnzqT0eWtFGeZt lqIA== X-Forwarded-Encrypted: i=1; AFNElJ9b+s9cl0fj4NI9TEhtgY4wIphvxWg4Z/T6d07FysqJaqfHcZmriNoSX61ZukqKP6TSWcZfL09vYShQWNg=@vger.kernel.org X-Gm-Message-State: AOJu0YwDZCAEaZTJZYeFoyzydLSJFeQt7rZ2Aosi01U4fzUEgyclu1Ag djwf56Gbdsvn5X48r2bEdnmw9K4PrelR7YPLTwhwFjaqCHKgAIgG69Ft X-Gm-Gg: Acq92OHLU6bD1/5E+TrZMUxMqWR0tVrCIdOqrwvVrvNyJN1dvzWiOsznBJSFEodIudQ D2zYZywOni/SX7mtbd9AHrVlNZylnA7+0YIa1y7MqPakc8UyILN2dZVx3PajTRDad8TT0UGGhed 6CwrFHle8qEq9BvUP/gmL579azEcwUJsbqur5qcYdfk54XUVMKfPD9DTWUOw5snw+VNnrShqz6u KHlUB1G+iK9PKpmQWEsvqGF8EoXTBy2AJ7LlLf/yYEyHkjhDgulZhuBwfTdlhBcrJBQAXt9D+VU sMOpKC3VfjD+tycyUELK+vsDKhEzaiOXTR/N6P0C+d7Gqym9UjjLgSkjoGNU5SoikZ4Y6GHbyjz RB5kbrqY/Xc+19oSqYkG+pnLeOSaEKUTwMRgo507KyGN57TO6eHwkMwaIkKGnM2w2jHfVDPDkOr 9u5H4FSEnEfN5tlXsyJ5PudmjHPPmQU3+kzvZmGd72nilvpVSuQ6m93hv+7oKHgu84laczoVl2/ As+vKMim/a5f8o= X-Received: by 2002:a05:7022:699b:b0:132:d182:3dd6 with SMTP id a92af1059eb24-13504515a28mr11108942c88.16.1779257266792; Tue, 19 May 2026 23:07:46 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-134cc2351c3sm27906026c88.11.2026.05.19.23.07.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2026 23:07:46 -0700 (PDT) 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" , "Pierre-Loup A . Griffais" , =?UTF-8?q?N=C3=ADcolas=20F=20=2E=20R=20=2E=20A=20=2E=20Prado?= , marshall@shzj.cc, hyacinth@shzj.cc, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v14 2/7] platform/x86: lenovo-wmi-other: Add GPU tunable attributes Date: Wed, 20 May 2026 06:07:35 +0000 Message-ID: <20260520060740.119554-3-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520060740.119554-1-derekjohn.clark@gmail.com> References: <20260520060740.119554-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: Rong Zhang Reviewed-by: Mark Pearson Signed-off-by: Derek J. Clark --- v9: - Rename gpu_didvid -> dgpu_didvid in documentation to match actual attribute name. v7: - Fix typo in dgpu_boost_clk attribute string. v4: - Align CPU feature enum values. - Remove gpu_oc_stat from Documentation. v3: - Remove gpu_oc_stat. --- .../wmi/devices/lenovo-wmi-other.rst | 10 ++ drivers/platform/x86/lenovo/wmi-capdata.h | 1 + drivers/platform/x86/lenovo/wmi-other.c | 105 ++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/Documentation/wmi/devices/lenovo-wmi-other.rst b/Documentation= /wmi/devices/lenovo-wmi-other.rst index 189dd4d31926d..011054d64eac5 100644 --- a/Documentation/wmi/devices/lenovo-wmi-other.rst +++ b/Documentation/wmi/devices/lenovo-wmi-other.rst @@ -69,6 +69,16 @@ Each attribute has the following properties: =20 The following firmware-attributes are implemented: - cpu_temp: CPU Thermal Load Limit + - dgpu_boost_clk: Dedicated GPU Boost Clock + - dgpu_didvid: Dedicated GPU Device Identifier and Vendor Identifier + - dgpu_enable: Dedicated GPU Enabled Status + - 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_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 c74a0e5294e78..a7cfdeaa58f77 100644 --- a/drivers/platform/x86/lenovo/wmi-capdata.h +++ b/drivers/platform/x86/lenovo/wmi-capdata.h @@ -20,6 +20,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 fe4cd7da017eb..9a6183bbcc920 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -62,6 +62,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_CROSSLOAD 0x01 @@ -639,6 +652,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; @@ -974,6 +1047,7 @@ static bool 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", @@ -999,9 +1073,40 @@ LWMI_ATTR_GROUP_TUNABLE_CAP01(ppt_pl4_ipl, "ppt_pl4_i= pl", 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, "dgpu_boost_clk", + "Set the dedicated GPU boost clock"); +LWMI_ATTR_GROUP_TUNABLE_CAP01(dgpu_didvid, "dgpu_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.53.0 From nobody Mon May 25 01:14:34 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 A7EF5371049 for ; Wed, 20 May 2026 06:07:48 +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=1779257270; cv=none; b=O+6HazEmjJItvNpSkxGM/8ZO+4VrcAggW9BKnkDaqP4XhVxDV1Kb6EjjXbP0IQbEGwDhP3c/aUSgftiiuz6jwsEASFJdMvwW3P5dG7Jg4KEMUgjjMJB0SQwrT4rSD+XK+F3TsxlWXjuqfwAj194jQ7j3+EDmXwC3gTpP/ROYDo0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257270; c=relaxed/simple; bh=SBViPiRUmhkdNzWa5VczX1quNP5nmjWucy5Pgexeu3k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TU/xvpRvLNpjTv9JjzvIqO42GJ1eoPplDda4hKzuoLwG7Kd8DTjjTooWcrdQfbpq9MengqMPaOSeigNUWJvBAYVCMTlxc1ADI1tWdqL80yJGmh78AqVneaDt1RfDPBvxOQY/2XCWlhJ+P4IgPjhKxWiQkS8+gAt6ocCuEExKCUE= 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=YJJpgTNF; 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="YJJpgTNF" Received: by mail-dl1-f49.google.com with SMTP id a92af1059eb24-1357c851a48so4573788c88.1 for ; Tue, 19 May 2026 23:07:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779257268; x=1779862068; 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=3wRTeD7dSyNFLzvhp1EB+mb3CycYaPY6lD8eO4/RobI=; b=YJJpgTNFxHnAduscznrTUkMGcT2J7nESUARzh4VD2J5WudJJ056+K6hgHozNqPfQq+ GSok4Lvn2vNOWackVaSpvf8oV3cqGCw6NOAyl71C/rXAlh1snFQkOZ+FWWbhLpFx1n9R kEIsPjq49r0Ow0j0kq4rRNH8zUK3ffx85bX81efL9kwb6fqTGH3KfoJORhDfUjCWBXBW N9ls2MrVJUDTrqmwW7iVOzx4KZBAYQCzz/axqtOL7GMf2RaUuPU5LEIItV+dewdu+sI2 9w1ZZq2ItCKk2f6QX2xabolp82TcI87XF7xd27sM+tImWwV0f+lD3RK/eXPQlr2foUZi HvxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779257268; x=1779862068; 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=3wRTeD7dSyNFLzvhp1EB+mb3CycYaPY6lD8eO4/RobI=; b=iAmp6mkETgxBezesdMQXWsJ3x4WljLAHE9t3EqKWczO/or2KxIUdF0MYy6zdVvl8nG rP+aTxTuzBR8EMY9tq+0yLFlMAYN6/9EaRUnvJ6pwjpf50+OlVGhm2wzHonJrqEtTLgR WQzruE+Y2/Yux5FUrI3NVOP7pzjLam+LP2oB1bxR+E3RSz7/4ByD05xDTKEN9tt20JQu uCE9/A/Vwx45cSoZGeOgQihxhziZu9xAv1EZfXS6+em61gvrGMfKqx0IFkU2si+C4VVh jTwbTtlJwlniF/LJ+8dwY7qqWrSbdqfl0e3VllILO97NdbYOismsVSdjkr7VQbTJi6m2 O7Ew== X-Forwarded-Encrypted: i=1; AFNElJ/J7d+FOEZRRFclW8y2ru7ryQUexjNiZXNjuukOmwoxBh3LF52p+JQXTLWUl8Sa8vsN6G9pfNV8+F5CHk0=@vger.kernel.org X-Gm-Message-State: AOJu0Yyn12w9ne3tozzypiy0BNS6UAub6Y63hk4h62gRpAJLkBZ8YCga EwiWvIHw3cvMiiPPZizYnETucdp3+CcK7iWLaAV4CjZmPrMxqagadW3U X-Gm-Gg: Acq92OFc2XCVa+kW1XCej4NU6c58bWaC9XBaavnZXuIbDwBDYpVZEIwAJPva/DNSG1+ KWroqee+Lw24ekyzFoAHW+itMCXbAZYoB7wuKudF2m7P876QDIeiW5C1v20NiES1auwxKBDAYts oqFETGV40xVVt/Is98sIvPOwrvd+F1HyoK6lh2EG+6yTQqREZ775RjGJ8NjXSHhFVihMZknBRZl ZU7oJw6ANhLLY3PKeIv7MNPc40deGrWXGYDdDTsOH20GWPe6r9tZvB1f511Mpd14XWnD2I1WK3R yEkeZY/RvrJiP/nd0iCm7Iso+SIyI9WhPwc0I+m5ejp416i8nN3zjDW1AcwWIb/f3sWwn6zCd0Q Pxb3zbq/kw8fdmMe0bxLbZl/DXOWpHOl4huKjebjVtOilPqpyh/0coaR7RJeBQR6iTZM/W+ewWX /y5XsYJEm8GMnzzq9IJqkxC5wgtr4xF9p4BQN6jnaYnTvfogUfdHkMPBKBlO7FzZIx9a0FrwJIo M5ce+LRbMaHEzM= X-Received: by 2002:a05:7022:e984:b0:134:fea9:f106 with SMTP id a92af1059eb24-135049487bemr8900758c88.34.1779257267597; Tue, 19 May 2026 23:07:47 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-134cc2351c3sm27906026c88.11.2026.05.19.23.07.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2026 23:07:47 -0700 (PDT) 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" , "Pierre-Loup A . Griffais" , =?UTF-8?q?N=C3=ADcolas=20F=20=2E=20R=20=2E=20A=20=2E=20Prado?= , marshall@shzj.cc, hyacinth@shzj.cc, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v14 3/7] platform/x86: lenovo-wmi-other: Rename LWMI_OM_FW_ATTR_BASE_PATH Date: Wed, 20 May 2026 06:07:36 +0000 Message-ID: <20260520060740.119554-4-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520060740.119554-1-derekjohn.clark@gmail.com> References: <20260520060740.119554-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, rename LWMI_OM_FW_ATTR_BASE_PATH to LWMI_OM_SYSFS_NAME. Reviewed-by: Rong Zhang Tested-by: Rong Zhang Reviewed-by: Mark Pearson Signed-off-by: Derek J. Clark --- drivers/platform/x86/lenovo/wmi-other.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index 9a6183bbcc920..beb92c7cff257 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -92,7 +92,7 @@ enum lwmi_feature_id_gpu { lwmi_attr_id(LWMI_DEVICE_ID_FAN, LWMI_FEATURE_ID_FAN_RPM, \ LWMI_GZ_THERMAL_MODE_NONE, LWMI_FAN_ID(x)) =20 -#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 DEFINE_IDA(lwmi_om_ida); @@ -1138,8 +1138,7 @@ static void lwmi_om_fw_attr_add(struct lwmi_om_priv *= priv) =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.53.0 From nobody Mon May 25 01:14:34 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 E1F5037266D for ; Wed, 20 May 2026 06:07:49 +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=1779257277; cv=none; b=BVAw0nAQC2uDIsFm6Y4P5DNznXgYfGmFBh9CwVor1WOAH/LpzFk9Td33rrmef4slzSMCatenBJc+20K34FipQrnCgxz5/ebc9G87ccpMYmyeilCKUXAHRRFy875UU868M8vj79xlQcsNh9zlgCP4WWR6Gu0KZOYq62ElcWVckQo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257277; c=relaxed/simple; bh=r9PDb8l4Ejd0DqwjYD1agzI8s95sqLtj2ByFGIOgtRA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ShbhtRcLP3Y9Frt7nNULO/3AkET3EOmyL/FJXOlxBUOOGe/LFAHJANgZDJrxxTXG1sGJfVCSIuI0X7j3sTcLSyE8BNPv9tyZMLT0VEBjne1CFGQmnBajAjlqrWKpL819To3jaBLn1BAYlwjzhug8VaKsF7FYwsVOHO+MWLx5uxE= 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=X9fB1SxW; 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="X9fB1SxW" Received: by mail-dl1-f43.google.com with SMTP id a92af1059eb24-1332772f6b3so5568358c88.1 for ; Tue, 19 May 2026 23:07:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779257269; x=1779862069; 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=BUHojJ2JRrcrb751ghtSKZHI9A8t6ikaDwFoZX8u+l4=; b=X9fB1SxWiD6HvNFPFXmJJzoTmWoHhaYs+GOfF0385jdH5VDneLqG6umSCW6T2xP7QZ pe7W5wPkYQaAyzNIgiwIbwZff9bfhctFEuGumIbPxJiJ4qWFkH93cAvUsCt9VMkxiLmh N1xLk5iQD/TUDPYeM6GNbdG7WYOHsSDsmTekXXCvdq9VM2RnIVBq7vwqAZU9FVXz1al+ NIfhobttJBKA/z+Ei9o9wqnZiHHcOH8x3L9H6QrBvwUbKFqORw03gQqnx4fox5Dv7uRH dAT3k6LkBXHMN6HfUGrya+z2UrPq00q6Jz5haT98Ab+0doUjGTMVlT6oCaW1GiDN5SKg 430A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779257269; x=1779862069; 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=BUHojJ2JRrcrb751ghtSKZHI9A8t6ikaDwFoZX8u+l4=; b=MgnmKXVsDhF2ncwVX0lLZ9jx7GreHKOr+nqdVLZUcecPhnk6JGA8H7CTiXkm0apsNH sN7yzrSSWtrjJcxBfQkQ7bsBg+dBghT+MohOXDKJimRIOAyyWz8mLhym0e6KjOGOgH2J hB+rtNrXkd6j4Lafqa9knd8zhHuPNL0hDoz1h4GS+tMEUrU21NpIDCKCwuCi+502zCIu pW0zR+KA8J+v54MSxsIYzaOXKb0Mw/8a/5d5W9gHifyKqIVlqy2T+GloFsbCJAynL5Jf 1VBudDsFCpZ2DjC25gIh7tT/el/BShjNzoYhLUKdCciE5IDsG4HtaCK4NqRlYC3NlJNH v82A== X-Forwarded-Encrypted: i=1; AFNElJ+ftO3tQHELoDnRR5NNOfilgZyf/7xsHo66DUmw5ak/+VNsQyQdySOPvU75LdCxfqPtgmrzzNFX4nl1fmc=@vger.kernel.org X-Gm-Message-State: AOJu0YxquYbypxZkVWz5uS+yiC94lVoNEcOGH7gJs7Guwvgb6quACXnz 6ChNDDbVLNYiRG8hSHU+fL8t6yUbS9fif0gZg2Po2XQamIHk/2p0z9CO X-Gm-Gg: Acq92OGuhXhgEjiQ3ga+ddBjfKTLjij0NS6r1iXbZbSRgk3mIgs+7X0L409dRP8W3/G hBNziIYEmr9idScgHsEEyj0BMts87PX5qtUG+0hSp9gjnbKUZCBp6ntR8TSaR0JgCRQny+uHsLs IJzfNnssWScAQ0t+Yp3BgtWfRU3qNDVKKnrq7agO5glzpIy6EXRAF8aRjT5I5wRYvzLmYpnZrNf sujT+ES7g5+XpTH1l4pt1xaTzurUMiEbOkuDVVjEAGk2awbB9RP0C78L82fTORhJ3Q8ORy0SyzB yTJR3XAw1wXuJZDZGkrNIlBIEaijwwNvijdYunQi78C/+NYxX6j7IDn6EnAGNRd7F5F1P2EHp8j hfMwxaYlqZea+xiezs0MA9687BHqnPdCRDuc07KQSr18R2MdxABRD/jgKJVzk+mnEJGsqi+wNd3 pL+//C/yXJnnsRPFTytt5Xer1zTnZunnTltojr1+tIT/jqn0vZjy7k7OaPlOsHZXjv4IoZKZgiP twC X-Received: by 2002:a05:7022:438a:b0:128:cf5c:535a with SMTP id a92af1059eb24-13504412e2cmr9318303c88.11.1779257268833; Tue, 19 May 2026 23:07:48 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-134cc2351c3sm27906026c88.11.2026.05.19.23.07.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2026 23:07:48 -0700 (PDT) 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" , "Pierre-Loup A . Griffais" , =?UTF-8?q?N=C3=ADcolas=20F=20=2E=20R=20=2E=20A=20=2E=20Prado?= , marshall@shzj.cc, hyacinth@shzj.cc, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v14 4/7] platform/x86: lenovo-wmi-other: Add WMI battery charge limiting Date: Wed, 20 May 2026 06:07:37 +0000 Message-ID: <20260520060740.119554-5-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520060740.119554-1-derekjohn.clark@gmail.com> References: <20260520060740.119554-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_behaviour and charge_types attributes through a power supply extension for devices that support WMI based charge enable & disable. Lenovo Legion devices that implement WMI function and capdata ID 0x03010001 in their BIOS are able to enable or disable charging at 80% through the lenovo-wmi-other interface. Add a charge_types attribute for BATX devices to expose this capability with Standard and Long_Life types enabled. Additionally, devices that support WMI function and capdata ID 0x03020000 are able to force discharge of the battery. Expose this capability with a charge_behaviour attribute in the power supply extension, with the auto and force-discharge behaviors enabled. The GET method for this attribute is bugged. After analyzing the DSDT, and some testing, it appears the method grabs bit(3) instead of bit(4) from the EC register that stores the current status, and will only report if charging has been inhibited or not. To work around this, store and report the last setting written to the attribute. As some devices only expose one attribute or the other, a bitmask is added with a lookup table and some helper macros to select the correct configuration for the hardware at runtime. The ideapad_laptop driver provides the charge_types attribute to provide similar functionality. When the WMI method is set this can corrupt the ACPI method return and cause hardware and driver errors. To avoid conflicts between the drivers, we get the acpi_handle and do the same check that ideapad_laptop does when it enables the feature. If the feature is supported in ideapad_laptop, abort adding the extension from lenovo-wmi-other. The ACPI method is more reliable when both are present from my testing, so we can prefer that implementation and do not need to worry about de-conflicting from inside that driver. Reviewed-by: Rong Zhang Signed-off-by: Derek J. Clark --- v14: - Change charge limit -> charge types in dev_dbg. - Stop casting u32 to int in lwmi_psy_prop_get_supported. v13: - Switch back to charge_types instead of charge_control_end_threshold. - Add helper function to reduce duplicated code when checking support level for a given attribute. - Remove setting priv->bh_registered to false during psy init. v12: - Move force_load_psy_ext into its own patch after this. - Use correct type casting for args in new functions. - Remove extra parenthesis. v11: - Refactor to use charge_behaviour and charge_control_end_threshold, per the class documentation. The ideapad_laptop driver will be fixed in a separate patch series. - Due to the extensive refactoring, I have removed the reviewed-by tags from Rong and Mark to allow them to recertify the code in its current state. v7: - Use devm_battery_hook_register, manually unregister during unbind. v6: - Check feature flags to determine if the extension should be loaded and if it is writable. - Zero initialize wmi_method_args_32. - Fix formatting. v5: - Use switch statement instead of if for battery charge state set/get. - use force_load_psy_ext to skip all ACPI interactions. - Various formatting fixes. v4: - Remove unused defines. - Disambiguate charging defines by renaming them to be more consistent with the kernel modes they represent. - Add module parameter to ignore ACPI checks. - Don't fail if the ACPI handle isn't found, skip the ACPI check instead. --- drivers/platform/x86/lenovo/Kconfig | 1 + drivers/platform/x86/lenovo/wmi-capdata.h | 1 + drivers/platform/x86/lenovo/wmi-other.c | 391 ++++++++++++++++++++++ 3 files changed, 393 insertions(+) diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/len= ovo/Kconfig index 09b1b055d2e01..b9a5d18caa1e3 100644 --- a/drivers/platform/x86/lenovo/Kconfig +++ b/drivers/platform/x86/lenovo/Kconfig @@ -262,6 +262,7 @@ config LENOVO_WMI_GAMEZONE config LENOVO_WMI_TUNING tristate "Lenovo Other Mode WMI Driver" depends on ACPI_WMI + depends on ACPI_BATTERY select HWMON select FW_ATTR_CLASS select LENOVO_WMI_CAPDATA diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x= 86/lenovo/wmi-capdata.h index a7cfdeaa58f77..a49229cec2451 100644 --- a/drivers/platform/x86/lenovo/wmi-capdata.h +++ b/drivers/platform/x86/lenovo/wmi-capdata.h @@ -21,6 +21,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 beb92c7cff257..8331da864beba 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -41,9 +41,12 @@ #include #include #include +#include #include #include =20 +#include + #include "wmi-capdata.h" #include "wmi-events.h" #include "wmi-helpers.h" @@ -75,9 +78,15 @@ enum lwmi_feature_id_gpu { LWMI_FEATURE_ID_GPU_NV_CPU_BOOST =3D 0x0b, }; =20 +enum lwmi_feature_id_psu { + LWMI_FEATURE_ID_PSU_CHARGE_TYPES =3D 0x01, + LWMI_FEATURE_ID_PSU_CHARGE_BEHAVIOUR =3D 0x02, +}; + #define LWMI_FEATURE_ID_FAN_RPM 0x03 =20 #define LWMI_TYPE_ID_CROSSLOAD 0x01 +#define LWMI_TYPE_ID_PSU_AC 0x01 =20 #define LWMI_FEATURE_VALUE_GET 17 #define LWMI_FEATURE_VALUE_SET 18 @@ -88,10 +97,19 @@ enum lwmi_feature_id_gpu { =20 #define LWMI_FAN_DIV 100 =20 +#define LWMI_CHARGE_BEHAVIOR_DISCHARGE 0x00 +#define LWMI_CHARGE_BEHAVIOR_AUTO 0x01 +#define LWMI_CHARGE_TYPE_STANDARD 0x00 +#define LWMI_CHARGE_TYPE_LONGLIFE 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 @@ -131,6 +149,11 @@ struct lwmi_om_priv { bool capdata00_collected : 1; bool capdata_fan_collected : 1; } fan_flags; + + enum power_supply_charge_behaviour charge_behaviour; + const struct power_supply_ext *battery_ext; + struct acpi_battery_hook battery_hook; + bool bh_registered; }; =20 /* @@ -557,6 +580,371 @@ 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 to the lwmi_om_priv drvdata + * @prop: The property to read + * @val: The value to return + * + * Reads the given value from 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 =3D {}; + u32 retval; + int ret; + + switch (prop) { + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + /* Reading from BIOS reads the wrong bit. Use cached value */ + val->intval =3D priv->charge_behaviour; + return 0; + case POWER_SUPPLY_PROP_CHARGE_TYPES: + args.arg0 =3D LWMI_ATTR_ID_PSU(LWMI_FEATURE_ID_PSU_CHARGE_TYPES, + LWMI_TYPE_ID_PSU_AC); + break; + default: + return -EINVAL; + } + + ret =3D lwmi_dev_evaluate_int(priv->wdev, 0x0, LWMI_FEATURE_VALUE_GET, + (u8 *)&args, sizeof(args), + &retval); + if (ret) + return ret; + + dev_dbg(&priv->wdev->dev, "Got return value %#x for property %#x\n", retv= al, prop); + + switch (retval) { + case LWMI_CHARGE_TYPE_LONGLIFE: + val->intval =3D POWER_SUPPLY_CHARGE_TYPE_LONGLIFE; + break; + case LWMI_CHARGE_TYPE_STANDARD: + val->intval =3D POWER_SUPPLY_CHARGE_TYPE_STANDARD; + break; + default: + dev_err(&priv->wdev->dev, "Got invalid charge types value: %#x\n", retva= l); + return -EINVAL; + } + + 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 to 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 =3D {}; + + switch (prop) { + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + args.arg0 =3D LWMI_ATTR_ID_PSU(LWMI_FEATURE_ID_PSU_CHARGE_BEHAVIOUR, + LWMI_TYPE_ID_NONE); + switch (val->intval) { + case POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO: + args.arg1 =3D LWMI_CHARGE_BEHAVIOR_AUTO; + break; + case POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE: + args.arg1 =3D LWMI_CHARGE_BEHAVIOR_DISCHARGE; + break; + default: + dev_err(&priv->wdev->dev, "Got invalid charge behavior value: %#x\n", + val->intval); + return -EINVAL; + } + priv->charge_behaviour =3D val->intval; + break; + case POWER_SUPPLY_PROP_CHARGE_TYPES: + args.arg0 =3D LWMI_ATTR_ID_PSU(LWMI_FEATURE_ID_PSU_CHARGE_TYPES, + LWMI_TYPE_ID_PSU_AC); + switch (val->intval) { + case POWER_SUPPLY_CHARGE_TYPE_LONGLIFE: + args.arg1 =3D LWMI_CHARGE_TYPE_LONGLIFE; + break; + case POWER_SUPPLY_CHARGE_TYPE_STANDARD: + args.arg1 =3D LWMI_CHARGE_TYPE_STANDARD; + break; + default: + dev_err(&priv->wdev->dev, "Got invalid charge types value: %#x\n", + val->intval); + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + dev_dbg(&priv->wdev->dev, "Attempting to set %#010x for property %#x to %= #x\n", + args.arg0, prop, args.arg1); + + return lwmi_dev_evaluate_int(priv->wdev, 0x0, LWMI_FEATURE_VALUE_SET, + (u8 *)&args, sizeof(args), NULL); +} + +/** lwmi_psy_prop_get_supported() - Gets the support level from capdata fo= r a given property + * @priv: Pointer to the lwmi_om_priv drvdata + * @prop: The power supply property to be evaluated + * + * Return: bitmapped capability data support level + */ +static u32 lwmi_psy_prop_get_supported(struct lwmi_om_priv *priv, enum pow= er_supply_property prop) +{ + struct capdata00 capdata; + u32 attribute_id; + int ret; + + switch (prop) { + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + attribute_id =3D LWMI_ATTR_ID_PSU(LWMI_FEATURE_ID_PSU_CHARGE_BEHAVIOUR, + LWMI_TYPE_ID_NONE); + break; + case POWER_SUPPLY_PROP_CHARGE_TYPES: + attribute_id =3D LWMI_ATTR_ID_PSU(LWMI_FEATURE_ID_PSU_CHARGE_TYPES, + LWMI_TYPE_ID_PSU_AC); + break; + default: + return 0; + } + + ret =3D lwmi_cd00_get_data(priv->cd00_list, attribute_id, &capdata); + if (ret) + return 0; + + dev_dbg(&priv->wdev->dev, "Battery charge feature (%#010x) support level:= %#x\n", + attribute_id, capdata.supported); + + return capdata.supported; +} + +/** + * lwmi_psy_prop_is_supported() - Determine if the property is supported + * @priv: Pointer to the lwmi_om_priv drvdata + * @prop: The power supply property to be evaluated + * + * Checks capdata 00 to determine if the property is supported. + * + * Return: true if readable, or false + */ +static bool lwmi_psy_prop_is_supported(struct lwmi_om_priv *priv, enum pow= er_supply_property prop) +{ + int ret; + + ret =3D lwmi_psy_prop_get_supported(priv, prop); + if (ret < 0) + return false; + + return (ret & LWMI_SUPP_VALID) && (ret & LWMI_SUPP_GET); +} + +/** + * lwmi_psy_prop_is_writeable() - Determine if the property is writeable + * @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 writable. + * + * Return: true if writable, 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; + int ret; + + ret =3D lwmi_psy_prop_get_supported(priv, prop); + if (ret < 0) + return false; + + return !!(ret & LWMI_SUPP_SET); +} + +#define DEFINE_LWMI_POWER_SUPPLY_EXTENSION(_name, _props, _behaviours, _ty= pes) \ + static const struct power_supply_ext _name =3D { \ + .name =3D LWMI_OM_SYSFS_NAME, \ + .properties =3D _props, \ + .num_properties =3D ARRAY_SIZE(_props), \ + .charge_behaviours =3D _behaviours, \ + .charge_types =3D _types, \ + .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, \ + } + +static const enum power_supply_property lwmi_psy_ext_props_all[] =3D { + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR, + POWER_SUPPLY_PROP_CHARGE_TYPES, +}; + +static const enum power_supply_property lwmi_psy_ext_props_types[] =3D { + POWER_SUPPLY_PROP_CHARGE_TYPES, +}; + +static const enum power_supply_property lwmi_psy_ext_props_behaviour[] =3D= { + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR, +}; + +#define LWMI_CHARGE_BEHAVIOURS (BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) | \ + BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE)) + +#define LWMI_CHARGE_TYPES (BIT(POWER_SUPPLY_CHARGE_TYPE_STANDARD) | \ + BIT(POWER_SUPPLY_CHARGE_TYPE_LONGLIFE)) + +DEFINE_LWMI_POWER_SUPPLY_EXTENSION(lwmi_psy_ext_all, lwmi_psy_ext_props_al= l, + LWMI_CHARGE_BEHAVIOURS, LWMI_CHARGE_TYPES); +DEFINE_LWMI_POWER_SUPPLY_EXTENSION(lwmi_psy_ext_types, lwmi_psy_ext_props_= types, + 0, LWMI_CHARGE_TYPES); +DEFINE_LWMI_POWER_SUPPLY_EXTENSION(lwmi_psy_ext_behaviour, lwmi_psy_ext_pr= ops_behaviour, + LWMI_CHARGE_BEHAVIOURS, 0); + +#define LWMI_PSY_PROP_BEHAVIOUR BIT(0) +#define LWMI_PSY_PROP_TYPES BIT(1) + +static const struct power_supply_ext *lwmi_psy_exts[] =3D { + [LWMI_PSY_PROP_BEHAVIOUR] =3D &lwmi_psy_ext_behaviour, + [LWMI_PSY_PROP_TYPES] =3D &lwmi_psy_ext_types, + [LWMI_PSY_PROP_BEHAVIOUR | LWMI_PSY_PROP_TYPES] =3D &lwmi_psy_ext_all, +}; + +/** + * 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, priv->battery_ext, &priv-= >wdev->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) +{ + struct lwmi_om_priv *priv =3D container_of(hook, struct lwmi_om_priv, bat= tery_hook); + + power_supply_unregister_extension(battery, priv->battery_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) +{ + acpi_handle *ahand =3D context; + + if (!handle) + return AE_OK; + + *ahand =3D handle; + + return AE_CTRL_TERMINATE; +} + +/** + * lwmi_om_psy_ext_init() - Hooks power supply extension to device battery + * @priv: Pointer to the lwmi_om_priv drvdata. + * + * Checks if the ideapad_laptop driver is going to manage charge attribute= s first, + * then if not, hooks the battery to our WMI methods if they are supported. + */ +static void lwmi_om_psy_ext_init(struct lwmi_om_priv *priv) +{ + static const char * const ideapad_hid =3D "VPC2004"; + acpi_handle handle =3D NULL; + unsigned int props =3D 0; + int ret; + + if (lwmi_psy_prop_is_supported(priv, POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR)) + props |=3D LWMI_PSY_PROP_BEHAVIOUR; + if (lwmi_psy_prop_is_supported(priv, POWER_SUPPLY_PROP_CHARGE_TYPES)) + props |=3D LWMI_PSY_PROP_TYPES; + if (!props) + return; + + /* Deconflict ideapad_laptop driver */ + ret =3D acpi_get_devices(ideapad_hid, lwmi_acpi_match, &handle, NULL); + if (ret) + return; + + if (handle && 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_ext =3D lwmi_psy_exts[props]; + 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"; + priv->bh_registered =3D true; + + battery_hook_register(&priv->battery_hook); +} + +/** + * lwmi_om_psy_remove() - Unregister battery hook + * @priv: Driver private data + * + * Unregisters the battery hook if applicable. + */ +static void lwmi_om_psy_remove(struct lwmi_om_priv *priv) +{ + if (!priv->bh_registered) + return; + + battery_hook_unregister(&priv->battery_hook); + priv->bh_registered =3D false; +} + /* =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 { @@ -1243,6 +1631,7 @@ static int lwmi_om_master_bind(struct device *dev) } =20 lwmi_om_fan_info_collect_cd00(priv); + lwmi_om_psy_ext_init(priv); =20 lwmi_om_fw_attr_add(priv); =20 @@ -1265,6 +1654,8 @@ static void lwmi_om_master_unbind(struct device *dev) =20 lwmi_om_hwmon_remove(priv); =20 + lwmi_om_psy_remove(priv); + component_unbind_all(dev, NULL); } =20 --=20 2.53.0 From nobody Mon May 25 01:14:34 2026 Received: from mail-dl1-f41.google.com (mail-dl1-f41.google.com [74.125.82.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99550372EF1 for ; Wed, 20 May 2026 06:07:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257273; cv=none; b=C9ZOtDWz3SQLoG0/3AyuZQ/b2Z0f2IdqtAhlNNHGaJ8j6XNtjYLr91lMkP4iU5eLRb04u27ydAoQ75gESCBGgu/H9eFdVhmulmuiPcW+9XsGPGCApesHz1nXnlk34p1t8i2//BGp/AqjLPxPhMd/B7TbVvfueYgVu2az5hlSDuU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257273; c=relaxed/simple; bh=ix2cnLN05qDVBqL5Ivaluk5AD3bR6qaGo0PGT4BxaMo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E3mTG9nfc6Us91wAUXwvJQjqoGK3yH/bFkpJgHGqNQpPRN+11iNKpOUCATUbDRaXSUKbfpSh3dYSywrhVQNIvQ8PmKL9KzT3xMi8/ApeVO6D/vDOPJZNmCvtGE/oIX06Xw7cZEpsQ776MHBA52xNgXMZC4U53JPDz2HwUy+Q1f4= 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=fxYSRCoQ; arc=none smtp.client-ip=74.125.82.41 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="fxYSRCoQ" Received: by mail-dl1-f41.google.com with SMTP id a92af1059eb24-1329fc4bf77so1378163c88.1 for ; Tue, 19 May 2026 23:07:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779257270; x=1779862070; 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=SuX4siZvKFowva4pFQaHeUAjFbZPfs27UZMsgCXTI7Y=; b=fxYSRCoQauABHXx7lDagQ88OUxLDvilxThsHgE8PYF2nh4++a4N3BFWrjRM6V/29z8 oCmbpxDEAOektH18tqXs0OFE5yfy1yzQDr/AmhN0eaFUMxU1pEsVQeHpmk0fZlseMG8A bBOm2KACnqMCd9WC9p0xYZ2mddlUrSvnjPlUD+gQi5rs6mR0X5H2NMpETAlyfJT1p0Vl H9t4rIu3Wz2/8tHxZ70Ic89oN+GaZcLDqg1L+hOuCHo6qlb1hZlHE+nnXeXfpW8fDGfs hv6JZ3iulDUvPkaj4Yc0B/FfgLB4+5bzn9KGuSlDkeX9yKG4fqKODJr0Esz3efsHD+ro ATXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779257270; x=1779862070; 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=SuX4siZvKFowva4pFQaHeUAjFbZPfs27UZMsgCXTI7Y=; b=G6PAvjRXcxemSmOdtyX+cKVs8kftfb3nGaYH9j256fB1/tEH1preZRXVCUK/vCd2jz XQ+O1ZRHwHcfoPmvIZJs3/FEXkHV2c4tE+/pekmbhpkAaBOUAolZ5E9c6JwTr8iGDBf/ DTKMfNXhZFoU0gS8SI5mXhqCrisL11Hx+v0353aSVFpg0EgeLBN5jgP0bloELJd8DvFh +8fUhkJkFBKHwWAnxQD6R/IfZ65Ywbt88Z80pz+gs/Bq+jWUQe3oRVQj/rq1QZ8fxdRM 2cO/tN8JRzyvWRZBRuVCgAfXYs9XY6PA8TJOfmUVbWD1uv8C6rybR90Fw4SGMZfxoSyU XCsw== X-Forwarded-Encrypted: i=1; AFNElJ+QM7IiDmXA/YyN0mIgnZh/vdvHSJZXvZFszcQQn2AoqhtxVjnxKZ3b2upLRcEUVsBnkJT8D3B4s4j452E=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4Pka/uLBHpYDKKbk/Q2ytL9GPVxuWUtczN/aEvCZIOcWlC2AL DqCCDgW+tWE0Jp4oWsy6SwzIR0YP2rtrcYcnVknSq9oJHE1lPnn/3X8P X-Gm-Gg: Acq92OGcQP7CF69Ho8l//IREG5UOTgrBW/C7getsjpMFgpkL9H1ERgCIgZvyh6vn+/B yZyc1VI/S8SLYd1ZcdhIpOwNDRkvRN3+RQ6rTZ2SA2T1NKbKRZ309SvK/RLTKj5ByOmA86KFRRe WSkxBAeN0QKT7dAu/2N/KRMTSY5vO/vP/CEyv+5GyGtOfPI/2//QLuV5E+jDA8zUMTkFGJMqz2t vQCwJlBqCU0Bun5Jc5r8h4LyZI2dNXJ9gKUGmrj8qmtwzufWa6sEcqPJVdXVqEXUl9jXq4uu9pw jE/3tKZRP3pey7EpHMbA2y6hy2y3pZo2Vv29X46xar58AL1e+e1MHXgEXNNOrh91J6IV0+trE15 EX0wchJeSSEwWLHT/PKxJ1AR7PMRSPnkAUpNaaMSMsUhjM8GYjcpNkt9xg1s9/tFPbA0TM4KB0j 6vl4Tnf5KuR8DCFttFPl/bs/xO6JZUVw2gOUmA4VmwcOTihOoy9h73sQzmwsf1YEIn0YoLEcKCE 0to X-Received: by 2002:a05:7022:23a9:b0:12c:8f92:c6ba with SMTP id a92af1059eb24-1350494f249mr10303932c88.34.1779257269645; Tue, 19 May 2026 23:07:49 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-134cc2351c3sm27906026c88.11.2026.05.19.23.07.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2026 23:07:49 -0700 (PDT) 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" , "Pierre-Loup A . Griffais" , =?UTF-8?q?N=C3=ADcolas=20F=20=2E=20R=20=2E=20A=20=2E=20Prado?= , marshall@shzj.cc, hyacinth@shzj.cc, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v14 5/7] platform/x86: lenovo-wmi-other: Add force_load_psy_ext module parameter Date: Wed, 20 May 2026 06:07:38 +0000 Message-ID: <20260520060740.119554-6-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520060740.119554-1-derekjohn.clark@gmail.com> References: <20260520060740.119554-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" Some Lenovo BIOS have been shown to have incomplete and/or broken capability data and WMI attribute IDs. In some cases the capability data reports that a feature is not supported when the get/set methods are fully implemented. It is also possible that the ACPI methods from the ideapad_laptop driver we defer to could be bugged while the WMI method is fully working. To aid end users in submitting more complete bug reports in these situations, add an override to skip the ACPI and compatibility checks to force load the power supply extension as if it is fully supported and has no conflicts. Reviewed-by: Rong Zhang Signed-off-by: Derek J. Clark --- v13: - Ensure is_writable and is_supported always return true when force_load_psy_ext is true. v12: - Move the force_load_psy_ext into its own distinct patch. --- drivers/platform/x86/lenovo/wmi-other.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86= /lenovo/wmi-other.c index 8331da864beba..fbb32bf404f24 100644 --- a/drivers/platform/x86/lenovo/wmi-other.c +++ b/drivers/platform/x86/lenovo/wmi-other.c @@ -185,6 +185,16 @@ MODULE_PARM_DESC(relax_fan_constraint, "Enabling this may results in HWMON attributes being out-of-sync, " "and setting a too low RPM stops the fan. Use with caution."); =20 +/* Visibility of power supply extensions */ +static bool force_load_psy_ext; +module_param(force_load_psy_ext, bool, 0444); +MODULE_PARM_DESC(force_load_psy_ext, + "This option will skip checking if the ideapad_laptop driver will conflic= t " + "with adding an extension to set the battery charge behavior and battery = charge " + "control end threshold. It will also skip checking if the BIOS reports th= at " + "those features are fully supported. It is recommended to blacklist the i= deapad " + "driver before using this option."); + /* =3D=3D=3D=3D=3D=3D=3D=3D HWMON (component: lenovo-wmi-capdata 00 & fan)= =3D=3D=3D=3D=3D=3D=3D=3D */ =20 /** @@ -755,6 +765,9 @@ static bool lwmi_psy_prop_is_supported(struct lwmi_om_p= riv *priv, enum power_sup { int ret; =20 + if (force_load_psy_ext) + return true; + ret =3D lwmi_psy_prop_get_supported(priv, prop); if (ret < 0) return false; @@ -781,6 +794,9 @@ static int lwmi_psy_prop_is_writeable(struct power_supp= ly *ps, struct lwmi_om_priv *priv =3D ext_data; int ret; =20 + if (force_load_psy_ext) + return true; + ret =3D lwmi_psy_prop_get_supported(priv, prop); if (ret < 0) return false; @@ -909,6 +925,8 @@ static void lwmi_om_psy_ext_init(struct lwmi_om_priv *p= riv) props |=3D LWMI_PSY_PROP_TYPES; if (!props) return; + if (force_load_psy_ext) + goto load_psy_ext; =20 /* Deconflict ideapad_laptop driver */ ret =3D acpi_get_devices(ideapad_hid, lwmi_acpi_match, &handle, NULL); @@ -920,6 +938,7 @@ static void lwmi_om_psy_ext_init(struct lwmi_om_priv *p= riv) return; } =20 +load_psy_ext: /* Add battery hooks */ priv->battery_ext =3D lwmi_psy_exts[props]; priv->battery_hook.add_battery =3D lwmi_add_battery; --=20 2.53.0 From nobody Mon May 25 01:14:34 2026 Received: from mail-dl1-f51.google.com (mail-dl1-f51.google.com [74.125.82.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 29D2C372ED0 for ; Wed, 20 May 2026 06:07:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257274; cv=none; b=WjIyBjKK9z9bNjdG1EYhMXcNMPVavv5WEUUhLlI1mcuS8xgAJaAQ6/klGAzTsrAVkFCOWlQ3r6E4u7LqXol/qb4R4cqKii5jrzf56jFRwW++5ImB+upieCmb6XazApMNAzdSSQlAwiqn+pbmOpKJ1eeRBH88Hm7jKs5qVDQtaNk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257274; c=relaxed/simple; bh=GxCFq9AI+jwh0+r6j6wu66r8AXdJi64J9r/mRxaMYII=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HuWpE8B5n34PWFHrqiLJjjJjKMBhzowDeecsW0xmY822yUTfOcxC91CLUvoycZKS5EtX5RlGv5CNGWCIm9wm61HBqDa+taFQ+7deMaEi1YPIzRWEhIWmi1EQq7FissUC+FLis1p8mxLPORD8nmWJfFXjaDpnuoi1rnYXbC9fvnA= 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=AoFQ3VTu; arc=none smtp.client-ip=74.125.82.51 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="AoFQ3VTu" Received: by mail-dl1-f51.google.com with SMTP id a92af1059eb24-1332772f6b3so5568386c88.1 for ; Tue, 19 May 2026 23:07:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779257270; x=1779862070; 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=Y/FEk053G9MxEw/xHdJE9UEmMYwdRskL+c4zHyrhNvk=; b=AoFQ3VTuJaB7ok0ehxhYsdyhpeHSJkVgHVToNMWE7ZTgqrcduNaF3juSrbSa4KKUlV U4P+/Lx5NIb+o16K6o38/iqq/hOlYW54KqXZbTaCvUMBsKx65KUV8aPm8JLViaKy6Tr0 SJLXXva7ca1uSZECr3DODsmux/+5ngoar+DJWSDajEtN2cGX1MzH5dKtHozVF0tw03wG D4wrSe6psB4QT+JBjvF2yX1fneYN0S7qN/TIPFqCSHcO9/dqM7L1SdnFTW4q7XZX+zXO KevxfvAQmc84QyhBPMqVYVDoP+qhZCOpbsq7u91s9ZRa6KH823OmLYtZLT1sZZl4LjXS VjPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779257270; x=1779862070; 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=Y/FEk053G9MxEw/xHdJE9UEmMYwdRskL+c4zHyrhNvk=; b=hX2IFm1fXOmYnWl0FeUjNgDM1rWNRBv+dMBVyc6zLM9NY2vKdFcTOUNJiw9KfLoHUP rj0GRbInny9+9DavgCOzn/jTL/OtiRvnaSRgxgzhlEhS43ioaIT5uLGsVOPP4EhWKsnk LsngtTTLn11jAeKnk5yukYlViot4Fpwo9IQgh8r+WE3fYY8w5nLwlf8nzWP55n4PuUdy X+rXWYprzuG4lbq28THC1mTkktKEMLv8IRBuX+mt1eQopB/xK0sVMWobAv3Py4gZi/PL kEB8AkVIomC2eNrpKPdQGcsEzX/rmeNv+/mEQVoSoIQ5SUWk6lLOVPyzbVDkAsg2Gc2m mBBA== X-Forwarded-Encrypted: i=1; AFNElJ9Sa5LQHXV9OXy9uQb8eVRrjz/gcMtdmcce+6/d/5S4HfwF3g9b8Kq93biq0jczyJdtvFQY+Nz5Er9qD18=@vger.kernel.org X-Gm-Message-State: AOJu0YwrbyzuzMjkP2dg/W5GQr8I/8S1z/6LiamSxMG6S998FVvcKEYZ yRXknFKriH0aoQ6hSf7lsWarYwntX4Vrg2uMOlaEwOyKMBI5ItuNtryd X-Gm-Gg: Acq92OF0/4MRTNr1FZeMaoEgtAVD8+2KmslpBZgmegRuVbHDScDpDAyij3Bu5X5+yLm tvzGpBX+HpMRQ7OUOHBRzEjXcVxl7e5a6TdoxlnH1rbdCCQ2LH7vNIlv8XYx9RSinruUN/ai9MB GeXdDDj/HDRQ/U7G+hYeeNI9Aoq6rtYHlwtWnvRN+MgM3cIA00snMX6jGd07T6tUdF9fxdF255g TnNZGqOnE97Imdv/3jaHkGft87CUO+xaZR0IQJ2n5iVoPtZbvkPNcWbiV7vSADs7xd3EJ7iy00M Lun5plR3Wq1rBycFX74DtJgsdWjsrkOzkdnNh79r43wZ+wSYoZzaid8iqvsKoPr4avCoFgxwH2Y yOvcox7zZu96Zhi4f7N0p/H9sUa1HO9eROrN62Jo+e8vPiUd8fUPJARIJC21f1YrXPNi7dc5KF6 CK2qINc9OhJBDwg16LJwjTMbV8G0NLBluL5FIDH46uScTDo0cESiqB0Rw8JrzLp43tEOy9EJtxe QVl X-Received: by 2002:a05:7022:2523:b0:12a:6c4b:9d01 with SMTP id a92af1059eb24-1350430f349mr8673149c88.7.1779257270470; Tue, 19 May 2026 23:07:50 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-134cc2351c3sm27906026c88.11.2026.05.19.23.07.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2026 23:07:50 -0700 (PDT) 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" , "Pierre-Loup A . Griffais" , =?UTF-8?q?N=C3=ADcolas=20F=20=2E=20R=20=2E=20A=20=2E=20Prado?= , marshall@shzj.cc, hyacinth@shzj.cc, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v14 6/7] platform/x86: lenovo-wmi-helpers: Add helper for creating per-device debugfs dir Date: Wed, 20 May 2026 06:07:39 +0000 Message-ID: <20260520060740.119554-7-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520060740.119554-1-derekjohn.clark@gmail.com> References: <20260520060740.119554-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" From: Rong Zhang We are about to add debugfs support for lenovo-wmi-capdata. Let's setup a debugfs directory called "lenovo_wmi" for tidiness, so that any lenovo-wmi-* device can put its subdirectory under the directory. Subdirectories will be named after the corresponding WMI devices. Signed-off-by: Rong Zhang Signed-off-by: Derek J. Clark --- v13: - Fix alphabetical include order. v7: - Use subsys_initcall() instead of module_init(). --- drivers/platform/x86/lenovo/wmi-helpers.c | 34 +++++++++++++++++++++++ drivers/platform/x86/lenovo/wmi-helpers.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/drivers/platform/x86/lenovo/wmi-helpers.c b/drivers/platform/x= 86/lenovo/wmi-helpers.c index 7a198259e3933..8f5766c391eb4 100644 --- a/drivers/platform/x86/lenovo/wmi-helpers.c +++ b/drivers/platform/x86/lenovo/wmi-helpers.c @@ -18,6 +18,8 @@ =20 #include #include +#include +#include #include #include #include @@ -185,6 +187,38 @@ int lwmi_tm_notifier_call(enum thermal_mode *mode) } EXPORT_SYMBOL_NS_GPL(lwmi_tm_notifier_call, "LENOVO_WMI_HELPERS"); =20 +static struct dentry *lwmi_debugfs_dir; + +/** + * lwmi_debugfs_create_dir() - Helper function for creating a debugfs dire= ctory + * for a device. + * @wdev: Pointer to the WMI device to be called. + * + * Caller must remove the directory with debugfs_remove_recursive() on dev= ice + * removal. + * + * Return: Pointer to the created directory. + */ +struct dentry *lwmi_debugfs_create_dir(struct wmi_device *wdev) +{ + return debugfs_create_dir(dev_name(&wdev->dev), lwmi_debugfs_dir); +} +EXPORT_SYMBOL_NS_GPL(lwmi_debugfs_create_dir, "LENOVO_WMI_HELPERS"); + +static int __init lwmi_helpers_init(void) +{ + lwmi_debugfs_dir =3D debugfs_create_dir("lenovo_wmi", NULL); + + return 0; +} +subsys_initcall(lwmi_helpers_init) + +static void __exit lwmi_helpers_exit(void) +{ + debugfs_remove_recursive(lwmi_debugfs_dir); +} +module_exit(lwmi_helpers_exit) + MODULE_AUTHOR("Derek J. Clark "); MODULE_DESCRIPTION("Lenovo WMI Helpers Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/lenovo/wmi-helpers.h b/drivers/platform/x= 86/lenovo/wmi-helpers.h index ed7db3ebba6cc..039fe61003ceb 100644 --- a/drivers/platform/x86/lenovo/wmi-helpers.h +++ b/drivers/platform/x86/lenovo/wmi-helpers.h @@ -16,6 +16,8 @@ struct wmi_method_args_32 { u32 arg1; }; =20 +struct dentry *lwmi_debugfs_create_dir(struct wmi_device *wdev); + enum lwmi_event_type { LWMI_GZ_GET_THERMAL_MODE =3D 0x01, }; --=20 2.53.0 From nobody Mon May 25 01:14:34 2026 Received: from mail-dl1-f44.google.com (mail-dl1-f44.google.com [74.125.82.44]) (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 7261337268B for ; Wed, 20 May 2026 06:07:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257280; cv=none; b=XzvhI1KGRpgheUq3dQ6XDfOM9B3iyVjZ/+E9xynIHdNoTm7yLIooriIXmXwSKT71JfuDgNqlcDsjYcUO1rSwYIIyICkygURv8+mHHzd1auruxcqBkI/RY9ZYoGBOuE2v2oUHBc0ZJ4vps849DAuVE8IZPgfOofLv7Bf9icFATJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779257280; c=relaxed/simple; bh=TjDUw7J3JP4g6lMvcIDMcm+5wDXorajT6a6RQD/bNpw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tPG7ucP/mG8EjyHvdvvdrjjbqaUXNGzjA8wXA0zYbeDBJgZiBkBj8UrED055boRmLtLd9PV0VbJ+jgf3Pis0wtcuCGjiQD0UnSEPwBTT8AvHB/Vfq26252B9uRGGbcEgvzmNtP/skuV4sjmnxEWZq7hB+zsdqRRV2uoqrmOrFHw= 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=UzYTk+B/; arc=none smtp.client-ip=74.125.82.44 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="UzYTk+B/" Received: by mail-dl1-f44.google.com with SMTP id a92af1059eb24-12c1a170a50so5523423c88.0 for ; Tue, 19 May 2026 23:07:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779257272; x=1779862072; 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=gZT7+mXTrvz3hi9/TnqJrENf7TqUCF1Jkqo9h+bHvKU=; b=UzYTk+B/rXhAFnzNjoXKzYwiOpu5z9XbZ2GYiyloxfHtbcaYnLaI0XUkYkAyzlgXvQ 7HPEl7h6ZmXaw5lXSJ5Brxkl+mqNccDDiJ9OQfsdcsMvQ0bcbEWGlZszG5leXDOsZwoF rDoSXZzSe1joWWDV7xSFQNNW1o7VNSmftWYwKjTNCmDnVv44lj2+c3/Nz9pKq8azRABh 9lsOTElVSFyx3HUE1BBDkTQS8Rca6ODBALtQPrZ8Fnd33FBcxslhaWaHY/7OTkwmZLk0 T9/hHj9AwE/3NKi7nxj8xyf8VDSgl4nmNJzbjoQCwVIZolHF82IGF/Yb1NivlY5GGnEo gLSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779257272; x=1779862072; 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=gZT7+mXTrvz3hi9/TnqJrENf7TqUCF1Jkqo9h+bHvKU=; b=jFSLQVMriHWJWc+n6uEnHlJTQ7d/9Z0d+xr8hQOn1BJDU2rMByFxUVXcBi6bL4RM4x gOi2eUhVAX/7cNfbopwhuq8ETRl3MQ7Aq8k+ebh2ur1VMchIq1PhYtLU2pGoRcRJXqP1 ICLrmQtpwidl1GHJWRFozgMdXgzusN1mKl43ifOaUGV+DoMcgAkmWh3pzT8eJDNUa+3k 1+bpcHpSr/Jsg7EbbL9ab4+hy6+uYg0QED3jiPl5iVE77wdp+rH4w3FIwzAYxtxo0AT4 HM/JWj//5MipWX49tvWlvaqfSoRSBGHvNa9GVWSz3721dBPXwSj1fyvGqsJh+STQUA0z EQXw== X-Forwarded-Encrypted: i=1; AFNElJ/keLz4gL14DlGaUuOpFutzUr3umArHsUsv/pubN7jKaIxUoEkX6LXP5dtEdRljp8hhOnVULdBfaRH0B/o=@vger.kernel.org X-Gm-Message-State: AOJu0YzkCWhZ2fyzrnakVRra7smX96T/FuuKnkIMQZus30NjAkdiLDrs mEi3nty201lW3/urReV8lHq+s9wENYr3dYADqPK81HwZd7pmCgeRfzSP X-Gm-Gg: Acq92OEhs/VCs4AZGhI0H4IqWVq10TYuckNLP69blhf2ZuH+fzri/dO8+CN9Jlv95lb AyIWBjB5EEB/tcQNBnTE/3mdLrTG5iZzGVijI07Dz8LbPtXXvu2IISgXAMey9Zju/MJnzqCd5wy ajIcrhTfN68bFADiNeBOzVPcsB26z/Z3FL70pGQLlCIW62fB7JqLuWlcSSu/I8JE1Sn0+rfeFbI N5aMvK2cKD9NSgGTVZF5yEg+rlbrw+Psuh0GnBOmDFeuinYNLKs4QRcf/XQcE7ufWvk0kBYfU5k EHpu6NvqQwArr+AlEAsDLD3opz/1/hQAp1kbTFxTNi3/h3qgjYVcuD+zbGI+g9ysyCl/B7w2uX6 duz2ltob2ArCYyGm9P7pCswg1dGVUWHMyXSCFfpKWWWLDOxakIoKcZaA2CKFRsuoPaZ2cVqiln3 vGFMhePmcOIaB+5eIokOswC+yIm5RIbsCFq+sJkqxQogxSZhsoXGJZJXCuP5F/ENdsSC6S3cxiw E0d X-Received: by 2002:a05:7022:6181:b0:127:366f:8bb7 with SMTP id a92af1059eb24-1350483cd93mr10912583c88.25.1779257271794; Tue, 19 May 2026 23:07:51 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-134cc2351c3sm27906026c88.11.2026.05.19.23.07.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2026 23:07:51 -0700 (PDT) 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" , "Pierre-Loup A . Griffais" , =?UTF-8?q?N=C3=ADcolas=20F=20=2E=20R=20=2E=20A=20=2E=20Prado?= , marshall@shzj.cc, hyacinth@shzj.cc, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v14 7/7] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Date: Wed, 20 May 2026 06:07:40 +0000 Message-ID: <20260520060740.119554-8-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260520060740.119554-1-derekjohn.clark@gmail.com> References: <20260520060740.119554-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" From: Rong Zhang The Lenovo GameZone/Other interfaces have some delicate divergences among different devices. When making a bug report or adding support for new devices/interfaces, capdata is the most important information to cross-check with. Add a debugfs file (lenovo_wmi//capdata), so that users can dump capdata and include it in their reports. Since `struct capdata01' is just an extension to `struct capdata00', also convert the former to include the latter anonymously (-fms-extensions, since v6.19). This is declared as a union in the capdata01 struct, with both the anonymous declaration and as a named member to avoid type casting when passing just the capdata00 struct pointer. Tested-by: Kurt Borja Signed-off-by: Rong Zhang Signed-off-by: Derek J. Clark --- v12: - Make capdata00 a union of an anonymous member and a named member of capdata01 to avoid casting when capdata00 is accessed directly. --- drivers/platform/x86/lenovo/Kconfig | 1 + drivers/platform/x86/lenovo/wmi-capdata.c | 120 ++++++++++++++++++++++ drivers/platform/x86/lenovo/wmi-capdata.h | 7 +- 3 files changed, 125 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/len= ovo/Kconfig index b9a5d18caa1e3..4443f40ef8aa7 100644 --- a/drivers/platform/x86/lenovo/Kconfig +++ b/drivers/platform/x86/lenovo/Kconfig @@ -236,6 +236,7 @@ config YT2_1380 config LENOVO_WMI_CAPDATA tristate depends on ACPI_WMI + depends on LENOVO_WMI_HELPERS =20 config LENOVO_WMI_EVENTS tristate diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x= 86/lenovo/wmi-capdata.c index 714aa6fd6f1fc..d5e9615661364 100644 --- a/drivers/platform/x86/lenovo/wmi-capdata.c +++ b/drivers/platform/x86/lenovo/wmi-capdata.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +89,7 @@ struct lwmi_cd_priv { struct notifier_block acpi_nb; /* ACPI events */ struct wmi_device *wdev; struct cd_list *list; + struct dentry *debugfs_dir; =20 /* * A capdata device may be a component master of another capdata device. @@ -117,6 +120,8 @@ struct cd_list { =20 static struct wmi_driver lwmi_cd_driver; =20 +/* =3D=3D=3D=3D=3D=3D=3D=3D Device components =3D=3D=3D=3D=3D=3D=3D=3D */ + /** * lwmi_cd_match() - Match rule for the master driver. * @dev: Pointer to the capability data parent device. @@ -470,6 +475,116 @@ EXPORT_SYMBOL_NS_GPL(lwmi_cd01_get_data, "LENOVO_WMI_= CAPDATA"); DEF_LWMI_CDXX_GET_DATA(cd_fan, LENOVO_FAN_TEST_DATA, struct capdata_fan); EXPORT_SYMBOL_NS_GPL(lwmi_cd_fan_get_data, "LENOVO_WMI_CAPDATA"); =20 +/* =3D=3D=3D=3D=3D=3D=3D=3D debugfs =3D=3D=3D=3D=3D=3D=3D=3D */ + +/** + * lwmi_cd00_show() - Dump capdata00 + * @s: Pointer to seq_file where the capdata00 is dumped. + * @cd00: Pointer to a capdata00 struct to be dumped. + */ +static void lwmi_cd00_show(struct seq_file *s, struct capdata00 *cd00) +{ + u8 dev =3D FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id); + u8 feat =3D FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id); + u8 mode =3D FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id); + u8 type =3D FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id); + bool extra =3D cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_S= UPP_VALID); + bool get =3D cd00->supported & LWMI_SUPP_GET; + bool set =3D cd00->supported & LWMI_SUPP_SET; + bool valid =3D cd00->supported & LWMI_SUPP_VALID; + + seq_printf(s, " id: 0x%08x [dev: %2u, feat: %2u, mode: %2u, = type: %2u]\n", + cd00->id, dev, feat, mode, type); + + seq_printf(s, " supported: 0x%08x [%c%c%c%c]\n", cd00->supported, + extra ? '+' : ' ', + get ? 'R' : ' ', + set ? 'W' : ' ', + valid ? 'V' : ' '); + + seq_printf(s, " default_value: %u\n", cd00->default_value); +} + +/** + * lwmi_cd01_show() - Dump capdata01 + * @s: Pointer to seq_file where the capdata01 is dumped. + * @cd01: Pointer to a capdata01 struct to be dumped. + */ +static void lwmi_cd01_show(struct seq_file *s, struct capdata01 *cd01) +{ + /* capdata01 is an extension to capdata00. */ + lwmi_cd00_show(s, &cd01->cd00); + + seq_printf(s, " step: %u\n", cd01->step); + seq_printf(s, " min_value: %u\n", cd01->min_value); + seq_printf(s, " max_value: %u\n", cd01->max_value); +} + +/** + * lwmi_cd_fan_show() - Dump capdata_fan + * @s: Pointer to seq_file where the capdata_fan is dumped. + * @cd_fan: Pointer to a capdata_fan struct to be dumped. + */ +static void lwmi_cd_fan_show(struct seq_file *s, struct capdata_fan *cd_fa= n) +{ + seq_printf(s, " id: %u\n", cd_fan->id); + seq_printf(s, " min_rpm: %u\n", cd_fan->min_rpm); + seq_printf(s, " max_rpm: %u\n", cd_fan->max_rpm); +} + +/** + * lwmi_cd_debugfs_show() - Dump capability data to debugfs + * @s: Pointer to seq_file where the capability data is dumped. + * @data: unused. + * + * Return: 0 + */ +static int lwmi_cd_debugfs_show(struct seq_file *s, void *data) +{ + struct lwmi_cd_priv *priv =3D s->private; + u8 idx; + + guard(mutex)(&priv->list->list_mutex); + + /* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */ + for (idx =3D 0; idx < priv->list->count; idx++) { + seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx); + + if (priv->list->type =3D=3D LENOVO_CAPABILITY_DATA_00) + lwmi_cd00_show(s, &priv->list->cd00[idx]); + else if (priv->list->type =3D=3D LENOVO_CAPABILITY_DATA_01) + lwmi_cd01_show(s, &priv->list->cd01[idx]); + else if (priv->list->type =3D=3D LENOVO_FAN_TEST_DATA) + lwmi_cd_fan_show(s, &priv->list->cd_fan[idx]); + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(lwmi_cd_debugfs); + +/** + * lwmi_cd_debugfs_add() - Create debugfs directory and files for a device + * @priv: lenovo-wmi-capdata driver data. + */ +static void lwmi_cd_debugfs_add(struct lwmi_cd_priv *priv) +{ + priv->debugfs_dir =3D lwmi_debugfs_create_dir(priv->wdev); + + debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_de= bugfs_fops); +} + +/** + * lwmi_cd_debugfs_remove() - Remove debugfs directory for a device + * @priv: lenovo-wmi-capdata driver data. + */ +static void lwmi_cd_debugfs_remove(struct lwmi_cd_priv *priv) +{ + debugfs_remove_recursive(priv->debugfs_dir); + priv->debugfs_dir =3D NULL; +} + +/* =3D=3D=3D=3D=3D=3D=3D=3D WMI interface =3D=3D=3D=3D=3D=3D=3D=3D */ + /** * lwmi_cd_cache() - Cache all WMI data block information * @priv: lenovo-wmi-capdata driver data. @@ -772,6 +887,8 @@ static int lwmi_cd_probe(struct wmi_device *wdev, const= void *context) dev_err(&wdev->dev, "failed to register %s: %d\n", info->name, ret); } else { + lwmi_cd_debugfs_add(priv); + dev_dbg(&wdev->dev, "registered %s with %u items\n", info->name, priv->list->count); } @@ -782,6 +899,8 @@ static void lwmi_cd_remove(struct wmi_device *wdev) { struct lwmi_cd_priv *priv =3D dev_get_drvdata(&wdev->dev); =20 + lwmi_cd_debugfs_remove(priv); + switch (priv->list->type) { case LENOVO_CAPABILITY_DATA_00: lwmi_cd_sub_master_del(priv); @@ -821,6 +940,7 @@ static struct wmi_driver lwmi_cd_driver =3D { =20 module_wmi_driver(lwmi_cd_driver); =20 +MODULE_IMPORT_NS("LENOVO_WMI_HELPERS"); MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table); MODULE_AUTHOR("Derek J. Clark "); MODULE_AUTHOR("Rong Zhang "); diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x= 86/lenovo/wmi-capdata.h index a49229cec2451..92098aeeee84a 100644 --- a/drivers/platform/x86/lenovo/wmi-capdata.h +++ b/drivers/platform/x86/lenovo/wmi-capdata.h @@ -38,9 +38,10 @@ struct capdata00 { }; =20 struct capdata01 { - u32 id; - u32 supported; - u32 default_value; + union { + struct capdata00; + struct capdata00 cd00; + }; u32 step; u32 min_value; u32 max_value; --=20 2.53.0