From nobody Fri Jun 12 20:17:23 2026 Received: from mail-dy1-f171.google.com (mail-dy1-f171.google.com [74.125.82.171]) (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 C1B5D367296 for ; Tue, 12 May 2026 23:58:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630294; cv=none; b=epCSbcCOD63/2FKHhNKMHvdOsbcjcadshX9Ij31kLGg5lvhPrS1U3mlpmiOltgsTgqDV0zdVDZrYy00+m8J6csW47L7nZx/f7J224cZR8sMNv7JS9PNypJGhU7FkSZi5Pe4XDR8tOffUsgb35JX6UFMgblZPq4/UQkzsrATlyM0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630294; c=relaxed/simple; bh=Zte2gr1E5NXIqpRr4wGKr1iDjlFOUsHvP47iuixPyp0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oMagIiCqS2DstSQcEDkm+gbX0PR55jeazR7jv+fpMJWjTRQofGDxo0VKmUzZegY2T3+qeODTgc2n6UuDfZHFRE3tjy4AkDh+kw8fVLIhinkE6a4nbTEQNyyM5dfoQSIeWShBM+69tDL81wziGS1ZmyWKh2/VvyWKgX4xAdJlgrM= 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=QEaDiQuq; arc=none smtp.client-ip=74.125.82.171 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="QEaDiQuq" Received: by mail-dy1-f171.google.com with SMTP id 5a478bee46e88-2f36da5c8fbso6114998eec.0 for ; Tue, 12 May 2026 16:58:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778630292; x=1779235092; 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=cCyJ+9jX4e90DYtbQtt6p1lGrl1zMggvXV09hpqVJbA=; b=QEaDiQuqhRIo8PazP3I466/p5tdCabWOkuY9g/QAkkTyydqf1cFTmwDAaA2xL+vEb6 Sp57vXiUUMAeniYpYQOJmVm2wQ+lgTBL7k/e/1ldj8Jqpc+USO0htzw8F+mMoTDElfzo OGLJDxxDdLO8MTunhkph3sjr59jh3ttLCvbmCTP2BlE1HN+eAJvHXGTEOruMwFzDPXaV cLGNuyNRd2576G3zzL82epZcqg+b9b47sxU09X55keE9/obblBOx2deyQaaCwALqtjPU WkXjJHDwgRmnmQtOSNqcXBEVLC5+MlX3bAmxcL3zt91RZAQpHIHdgd36LkBicoOTqsrx zz4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778630292; x=1779235092; 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=cCyJ+9jX4e90DYtbQtt6p1lGrl1zMggvXV09hpqVJbA=; b=AF+FYs3p2Dx+sQ381iF5IO9k1sns3+4ZfmIkhp0SHdwgUZmfWrYf6BXrP5tCxnOV5M gDZ92A+WA7xuVUaUbgjAF53RJppGNn8ztG9YDQadvPuavBONIdkO93OFDuvWNeSjBeBW u1OMkT0tawh3Nqgafter/ihMRIxOenU5VUVwQkfPlHx2mQfIq9+cQRV+XjdaIduD1+Oj Gqjvm0CSsanG5yThyEX9pFlfc8H1kUnjnsqrazkqOjw9WvbMKQy2YyjCDeocN5cth8Wt 7NKGb8knlEwKl73RrDd54cC73gyPHPc+ICxRV1jSTt9q5YYtjRGl+GLi+o/tOyT2OOUn DobA== X-Forwarded-Encrypted: i=1; AFNElJ8n7M6WRvGbrYDEWkdRv6MkqKkUS79O5JUz1+dKzeY4waMTGVwiFzVccHGM/14laTgFsAwNfVLfoPW2NvQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxaRDH1HvtvIr8Uug4V8n7gPWs+ponXe1aFxlkc5SyxbImhbsbr Pz723A7voTd+bbDV9JqPY+syuYHOzpPsmS7IBSTMT7uRCuSiLweYpb2i X-Gm-Gg: Acq92OFDI//TNqYFZ2Ybui9/+zElC1UY3Evfg23thzls4eJDxJk9UEiyiKe2ZsqntLn pfXiM4wpeOexbxQyNIGOPWyk1E8xZ31OmmXHZD5KtWU2eFFwy6M8KFFh89EMDXqiBTB5amdnnLe HcnYGgmfbEq+cKrR58pseoa+f1rv4Yu/f8LSQIy/vkhjRofrZTlv97fWqZgyaqqo784WUz00Y15 m29BP/d73xxuTSfDbhgo4eF+uiisVTv3m7ezDXCxKplhnuxjuTTN8SMD5/8oB9mvfTr7S3nPOkH 1aiVatxvhQnQQ3HAjKBoMTnKCrxxl2AEMlRSJpUx5lOtqgTk1abtVHX4remi+V/FNfZBPbHGQoE /0TTWv1J59x5u2+/AUJsaayDCg7Y8ZsWnHIPccJQV5x+g6m62XXEjC7MxXv9HfKmbQK2+uBby7+ KvrspFOUuiYT3iisQqJiB0iWw/10CNeqhAvOBjP0fSgAta2DIyST/Pu6UhfBuF7V7MfCBZWp8kP b4G X-Received: by 2002:a05:7300:7245:b0:2fc:9d97:d59a with SMTP id 5a478bee46e88-3011a467dd6mr702842eec.32.1778630291911; Tue, 12 May 2026 16:58:11 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2f888e3e285sm23625851eec.27.2026.05.12.16.58.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 16:58:11 -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 v13 1/7] platform/x86: lenovo-wmi-other: Add missing CPU tunable attributes Date: Tue, 12 May 2026 23:58:02 +0000 Message-ID: <20260512235808.691046-2-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260512235808.691046-1-derekjohn.clark@gmail.com> References: <20260512235808.691046-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 01d471156738..189dd4d31926 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 c3e760b8c3c3..c74a0e5294e7 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 d318ba432fdc..fe4cd7da017e 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 base-commit: 2997606dd17729404cef9821ce66dd037b6019eb --=20 2.53.0 From nobody Fri Jun 12 20:17:23 2026 Received: from mail-dy1-f182.google.com (mail-dy1-f182.google.com [74.125.82.182]) (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 6E6E83672A3 for ; Tue, 12 May 2026 23:58:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630295; cv=none; b=SuL7eIxs5qctWdkjXx0HzRcY7yquu0mAu4fTaK1xAVRyxXgOYopnajuZp6lNBTI2qKpxD81EkmV4kX0QmtVfh7JWmElTqQlOmbuv5yl21EDnZpJdciwZ3yXOvRa37R3jPVfzfcY9ZJ6DeC2HPowzJVe65r4LJCYqBvXkjM3uzyw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630295; c=relaxed/simple; bh=rvojeIv1BQiFfb3DDRdU0B9ui3JU/k32oaCEKfeIpmw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R1XaJ1BgkvYy7Q7sll/jKKEZHIO5Jm6yeqt7Yg/M5fxijObl4wrFQqUs8q9Fc72sJ7uD9AwNHUXuYfla6ZMn+f9PWaSjm73/zbe1qIz1YBwx/t2cloNsmINoCdiKM03hmz7WjRRVJjUgdresByboZd3+bZ9JeYFdEJeLqWD/Sy4= 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=oKDlu4FM; arc=none smtp.client-ip=74.125.82.182 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="oKDlu4FM" Received: by mail-dy1-f182.google.com with SMTP id 5a478bee46e88-2f3c623322bso10249721eec.0 for ; Tue, 12 May 2026 16:58:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778630293; x=1779235093; 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=/UBVkKH4Kze/bUuhmNNSBYFdBbqKSs/Ls244+CsLG0w=; b=oKDlu4FM3ovc9JSkJ/BCQfuyJofeIPIKhPaTZMfsF1IWZ9NM7CJQC7ljL3/jjK1Zr5 pdE06u/lWs99hPSo392W4JTLyqNWuvtL0OG1QbKXziLvkbn0Itv9/PkWfWdcE4Dzv/AG o3bSptluChGZGw6oIp8EMaN/ijT6czN89pPB0i/Wsyb5F/5cWXT+l3HW5HGqjTFL83I/ BKMVIGc6LhbwbNqaHfb3LZjkfOJz9jZhVD91/6ROZoTjtHBt/BwJ1sEGcspWY2UDY4Ag NjeFXJPF9LBB/5p85pDwz5yVGzhRt26UzBc9xVib6oy4irW/IaHyUO8IQU1XaG6KLxqe Cdww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778630293; x=1779235093; 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=/UBVkKH4Kze/bUuhmNNSBYFdBbqKSs/Ls244+CsLG0w=; b=VCH+fbOJLDetq8m7vr+Y1KmVY05fv+9Bh69BF42v45KKC135pBt1PjrwwQ4BO/JEz0 nceDWAHROUVh1EAqFLB1J0uw+X71uMM4pftanLuaMVtN2UeOeAZ/K+CJj2ogpJ/IKniX spHnEHeysqeBqEiqXsFyNvZADUcjEvpEZTw/zgh9EbvSP0w4lMAt/agpwZn7WKUJSAKU fbjs3MBgLgxef7nEN2nDqW+vjvXHCOM4eTPYo0nhSiQZ2e2Pf7HIKjebokrI0U1Iq1wp Iozj5LfcvEnzFCK4kBZrPv/N11n81o73Xf4Q/gd9+SfICHJ77FmRLzNd6WilUpTO3YAc 6GSQ== X-Forwarded-Encrypted: i=1; AFNElJ/GG1xqSDXCobq4us14/cZnazZSLKjBHjXWdfnInKZyAByHG0dFOqsMssLPH7BSzwIbF84rdZPecCaXtxk=@vger.kernel.org X-Gm-Message-State: AOJu0Yw1wtHyaAZnC9UMUJnlnqpLiKZD/CVKI0lxXapkzCMd7cG/lJwJ B6m8A8W0jCku7wB+JR0ZhtYw0FhD4WdRaah4z5Nblvsn7KfsvIGc/Zaj X-Gm-Gg: Acq92OHj3gWr4pSonfiHMPhzzRq/AwbfMxyXKvkOtGBNiaZc+/KJZjVumqlzu6I6pk0 iTQVrxoWpw7RC0xqNQR1WV6oVcNcXrtcE9ko3Y2Vj6XYqtC6hob6gqRqSX4QnqM7zbEwrUcgh4M t6qWb0e8RQmiB9Nr1H1QulsqQ6K5/ylDO0pMoavdWAS0L5FWpdMVp8m4uIfPQnxIjIsoICGJp5j dhtiNJ2zd9Y24oGABvPdNvuX5VT8hwiWSCs3up/DbY5gjnyDCZ4IR2eZP20xaWVMMijA5zc9+tO 6EskjP3qtLP0pWDunAT8bre1RqAxKbuv2G+YN27+BMks1Z66XQQPUoxZgILRcR5xdGzboW+ikYK I9td5esh8YTDlHxkjnsPFZ0CG4XPFmFy/wFNBHOCDX3NIBhtSch3QaxqhBdNMSoRxfsVbvni4L/ 1AIT3Tn6+ugWhRN1/Dde6qKMa4aCAva/468SF0340w4XvVChSvaum0L5giI03R5T6xB65mW6m1W 9zc X-Received: by 2002:a05:7300:d021:b0:2be:142f:d499 with SMTP id 5a478bee46e88-3015593e346mr234472eec.16.1778630292673; Tue, 12 May 2026 16:58:12 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2f888e3e285sm23625851eec.27.2026.05.12.16.58.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 16:58:12 -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 v13 2/7] platform/x86: lenovo-wmi-other: Add GPU tunable attributes Date: Tue, 12 May 2026 23:58:03 +0000 Message-ID: <20260512235808.691046-3-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260512235808.691046-1-derekjohn.clark@gmail.com> References: <20260512235808.691046-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 189dd4d31926..011054d64eac 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 c74a0e5294e7..a7cfdeaa58f7 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 fe4cd7da017e..9a6183bbcc92 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 Fri Jun 12 20:17:23 2026 Received: from mail-dy1-f182.google.com (mail-dy1-f182.google.com [74.125.82.182]) (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 4665C2E173D for ; Tue, 12 May 2026 23:58:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630295; cv=none; b=an4q+VPxdE7SC8gi6RNkjJJXFDFlRi7Lj8ldIwUb2NX0GxeJXkz0ZyNAsO6jGiZ4Ix1rmwA6CfVwY06MTU2oR2kxg7OhNneudou4uIXRZYZV8jiOdzg3EsObUSyejCI4ojlb9HdeeHE1Q4uiwzBuBixP71wKk5/Yu4z/a4OvLHI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630295; c=relaxed/simple; bh=Id93/UmAkBayU5XfSGvwm0lXSys0aFHC0XBVBr6Ke64=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LO3txrU1mArCAWLdZeMi4TaAyd9C5qC8xAJyNJso1gHUS2acWgECnLFQdNoMZsIdHBJWBYCdIC85L1vPja99IojJ3ce/sD+Y3sHAOhP72SbEaagI+cWWNfD0nFECHtxssrKiPcIRe0aLKfWE1/D2hRFRe0pNjoMWqHK4lRSVJTY= 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=YNO0MrLx; arc=none smtp.client-ip=74.125.82.182 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="YNO0MrLx" Received: by mail-dy1-f182.google.com with SMTP id 5a478bee46e88-2f0ad52830cso9028456eec.1 for ; Tue, 12 May 2026 16:58:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778630293; x=1779235093; 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=aWqsB4N1kVJNFFXBSICu+E9ixr8c1InK11jT5wOF9tQ=; b=YNO0MrLx1vvJ1Vd6lF9bMJLtZHTBj9+fLXYMoELzxi/TX8mHD952W2FQhvHM3qrY9+ chwKRB0V8KGFfF0w2w6CJ5max5FdErDOqA5FXXMpsDRNPxRE7TDBpLKcQHev85Jg2jgL BhK/0AK9gqJroQ/500/LXFYAuy2W8Epf0VyxXNUI5Jzrr0cbx3eIi8bQxlTMbpmQHE0E DhrwnIjoSCJ1HqFXrgBJ/HESfCKLIUVAIyagWBNZB6a6e9kwSvuaKNN5Lg3LoEoufBKz VuEUoBVmNfEl7zqnj+Fcih07mOut1WbX7AcZeHrF0jHKuPPhnspeeDsP/fJIl1AwuXIO rvcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778630293; x=1779235093; 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=aWqsB4N1kVJNFFXBSICu+E9ixr8c1InK11jT5wOF9tQ=; b=Tr2ZX9TccXosUeMxyvio5yWmo61e1EK+ORjRn0HS70qQnO80dCm/vM/QWO+3KmWNhB yQuSohx+64L5jbwvwP6QPPtmgB1aIWVhPRSq3jF5rfgbX3vL79AIPhn1IPZwt0IgNGak giw5peM1OA3aNEdQW9lkwejZCm/JDRT8ea9h4/pbXZYTLaeVYDeLNU8wKfadn7xTl8aN 53cT1ZDj5/tcsCgjUOm3N75jNVJ6i7T/NprWYtCDquiJOOJ6Bi4UywcSnkFIZfp5s6SR EHR5rZromEqUvDX+vL36/cgDH7GCyLayHm7r1wu0HqMH7mQysSSpSNgM6MAz3vfcUtY+ Jubg== X-Forwarded-Encrypted: i=1; AFNElJ9Ge4Iq79mKOOtJQzQv7jpWNKZZUReuixiGBd7waT7v6ypCadNKr44C2wk1l0geVbNb73mhU1sLX0xION8=@vger.kernel.org X-Gm-Message-State: AOJu0Yw4M8lk2m4zeouUmqvIy+NwexRcWTQDh3qx04QHOS2NZtdlpKuC JyRcICnTY7T5upF7/B+bYTZeaVTzLrUBKwkHUufx327qIZ+GSRpGMY+u X-Gm-Gg: Acq92OGbzqsXIS1TTAGYm+kFyExfJhOzZ1T8kMypq8WsIxCIbHZUN6n4PHQd1SifCYT Hmes5Wn41ZX+naC2P/r5WXXUvsafmqu81EsC7KrmMFWl80/KSQWIgjjReW2fg0S8z2jaEgLu5SP itXEN/2gGHOAiKxSU0ZFk+vomrxPzcOSVzlhvorANa9NOt7sIjEiBRmBnWgYGVqs+k426kEQkBX rKqbh7Em1nmp0FpARuG6UlVFIlcH9mWzD70O3s+S0CtOwmLTjFVMaKXiheM8zsOjXnLaOWTGb+l GqEC9HpF2nnD9Lae5Jw5cgylHrJQGsjz4FsnFcBjclYol+sTFr/xi3lufKxr667cq1ttPAFBcjF dBpXTlTSjHiOSSUEEbBEzSf0xKefoj6VqMr00BNXUUkPGoWI4KBQ/YfgfgBhLDljXRr4wCQDUIM NLUEcR9ZikzV3qMLXeL/V8ItuDwqwONt0Rs1euvZd6GMIIGrN6joVxJJl0ANdegAVAjHbSxSgXc Ialv+q1F9oqspY= X-Received: by 2002:a05:7301:607:b0:2d2:c60d:4fe5 with SMTP id 5a478bee46e88-30117c7ed7bmr744899eec.6.1778630293399; Tue, 12 May 2026 16:58:13 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2f888e3e285sm23625851eec.27.2026.05.12.16.58.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 16:58:13 -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 v13 3/7] platform/x86: lenovo-wmi-other: Rename LWMI_OM_FW_ATTR_BASE_PATH Date: Tue, 12 May 2026 23:58:04 +0000 Message-ID: <20260512235808.691046-4-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260512235808.691046-1-derekjohn.clark@gmail.com> References: <20260512235808.691046-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 9a6183bbcc92..beb92c7cff25 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 Fri Jun 12 20:17:23 2026 Received: from mail-dy1-f178.google.com (mail-dy1-f178.google.com [74.125.82.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1897936F8E7 for ; Tue, 12 May 2026 23:58:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630297; cv=none; b=p9eOcxwvwXif1MIwrf/UVhLTxNBnEbmepSvpWQQn7GShY7fhcwIXOqZ9tgXqPTktAA9a0PLQqL3NsL4hL76vNnVGi+HRHaKU+SnEJ2LAklWkUhk88zRzVBypmi4OwZ5S7DdIl5MvY5oogmzOqEEcG9dn7k2Rz152lFN6C2jpKjw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630297; c=relaxed/simple; bh=tnKIwSRG42ieczG3wNX94sfJRu+OY5++SwjknjD2D4E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=A0c37+dFwXA+2Gki/ndN6EmoIYIIMo84l/QnvA9u7ntitud3I6MNvOIKreb1r1ZQTpEbBZeRyUzjqR/UO9Vz+N7MqdWuxFD/QVALVnUqyYmOEESOB73DdvE0xrL29Id/8pa/1P4Bb8yZudRfYJD5MVsXl89nr1srcG16Xi0tBRE= 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=TTnZx8xH; arc=none smtp.client-ip=74.125.82.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="TTnZx8xH" Received: by mail-dy1-f178.google.com with SMTP id 5a478bee46e88-2f36da5c8fbso6115037eec.0 for ; Tue, 12 May 2026 16:58:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778630294; x=1779235094; 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=zqSHX2AgOYIsr1JiV0saj2NCpwr5noJFsDyG+tZ9cOI=; b=TTnZx8xHFxM8o5sSXadNkR8r7wbCehcJcmAYfRMrraE3EQ7YoU7QqGTZ0DberEgLId ugBDjM6kF/Fh4NEOXrwVkBsBgv4dJ2jb1FVyK7vuHLm42q1mnweO0X32Bay/iEGwc1aq p1KXrwsi+7JIOHr7seo+EaOxgWZQHYc0PdZH2o1PIpzpaaU1KFm/wzXK4V28EoAIZT8U dIdgRbMICxhWSuzFTwPH78X3vwSmkUvoujKhyUVHMReiqnHeGGK9sQO5ycc/l7LPjbJh RTXTIYWlUpvkElBg1ZzI+jUpx1/K7hplpwiXj/Q/h7ewlvL9mxslSaSRPfD8xUDbFUfw wNHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778630294; x=1779235094; 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=zqSHX2AgOYIsr1JiV0saj2NCpwr5noJFsDyG+tZ9cOI=; b=K8o/lzItaOx/v2KYB864z95MvMOawiyDhmqju8DNLfRGxg6f8eqjzCiOTjCOtantJo Sx6723AExn6BwOxDmxSNV8VuaJfJuC8Jz0pIeUIYIQAMIajS3u45WFdpGEdnMzXO2sEe KNCYKapBeDUEIykgyJ/PoL4wsRcQ8Hy6uL3GDcpYUJd2JLWshTw784QwjFVcpobiRemv OA6Uh9mOGXZpzhbbZ0wIx+Su2mt91qt8HLVKLX3XIBhKKIDLoUNZKIa2LPx2+BmYKEHs 46SPETodfnoXVSbIw2QMzrvJUrwza1jKCZ3CYaKP361hK60SqlTmUNb6kSgeosP8OUZo Espg== X-Forwarded-Encrypted: i=1; AFNElJ+NnYNxJwlsZMTBO++ZyHMutEgLSRBJ+rHdJ4XheupO0BZC7xApS/CWLuLR2T67QEVXtR7xAXoWSVGZ8Xo=@vger.kernel.org X-Gm-Message-State: AOJu0Yz4tORTJpdYh5/+EEeRUrgi/RppX+x4QtIWXtW07yC6e7mPlc/8 nQF9ujmVCucXklgG0Albg37EXbU9K+3T3+Ra5xi67MxroLJPKhNjrHY7 X-Gm-Gg: Acq92OGboNVKrGA9N77wq+Abx8Rw5i7fZV8rBgKArxKxZG9GlUd31Xi20x7zrnTnHOp oZK/cz4mpfwjmdxRhQPYQ/g91fzcwXe3S25hO7VasmCRZkwG/fPh+v3F6GAsiKHGT7jZl6YdWRV 5d0HgToLSUmvwjf5sZz82H0hFFldTiAWxQpckh+IWlzNguCPbfLTBU1VbMFYY5aOOeK2+YWlEu5 1/lJbB8pJHI3s0OQngQe+Yz7vwx6su9B9bPmHGdoTO+1A6F26n8MJ9Fd3l2rgu9Ffx/n4sGaqTO +sDfATI+CUkff1f15NCHCSgP9vdQf0UZ7+VYhfFWduQ8qV0aGTE9FLqnocIgx7nrJehyPL5sCHx 6hLouqiQqp+24cw9qj0muCnYq5Jhu9O7EiUi4ouxaxi8gxmOzndtI4biYdQhoj5kdO+jHc9PCRS oGz+lbjnlzWiDUD8x/AfGeltNugsiHi+RHq5umRkNYCqqaXlAyAbXfV+an8zd2LyHzz6wDIEqfA nFZ X-Received: by 2002:a05:7300:b54d:b0:2da:44ac:6d17 with SMTP id 5a478bee46e88-3011996d2c2mr603980eec.17.1778630294167; Tue, 12 May 2026 16:58:14 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2f888e3e285sm23625851eec.27.2026.05.12.16.58.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 16:58:13 -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 v13 4/7] platform/x86: lenovo-wmi-other: Add WMI battery charge limiting Date: Tue, 12 May 2026 23:58:05 +0000 Message-ID: <20260512235808.691046-5-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260512235808.691046-1-derekjohn.clark@gmail.com> References: <20260512235808.691046-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. Signed-off-by: Derek J. Clark --- 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 09b1b055d2e0..b9a5d18caa1e 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 a7cfdeaa58f7..a49229cec245 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 beb92c7cff25..a423bd563291 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 limit 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 limit 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: capability data support level, or an error + */ +static int 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 -EINVAL; + } + + ret =3D lwmi_cd00_get_data(priv->cd00_list, attribute_id, &capdata); + if (ret) + return ret; + + 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 Fri Jun 12 20:17:23 2026 Received: from mail-dy1-f178.google.com (mail-dy1-f178.google.com [74.125.82.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA5BC372075 for ; Tue, 12 May 2026 23:58:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630299; cv=none; b=Syf6gW0sjIA1+S9bOEWNfx4tLZ8frmn1W9TRwMm3TWYuT7IG5feXaxfw17xbH+xK4b473daHhQQFXa28QLg96DDSGElIPRutrI2DguCS9FuB+gQ892lrx/pDU4OgF2ISta3FkFGkpnZgj/dRIXCyXB+NeTt72N7IQ/h1Obuq++8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630299; c=relaxed/simple; bh=vVU5ca4ZrYFEp728QuuxNejz84yy8dbrZDDgPuVxjdo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NFgWRaSRjOY/3DhFjYcbXJ4hwn2xjM7yB2lqaMkCJCQtLIBUyEmmSFhTf2wNXXwVeoV0aJYwCq8pOVpDfTFDbwvLTPooD7TEJSmav/tApj/TflMHBVNJ5XDcupfcRFgR6adhEfMhmlJp5RNO94dY15grdRNLgDxE7C0uqzq4ft0= 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=qTcD5QV5; arc=none smtp.client-ip=74.125.82.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qTcD5QV5" Received: by mail-dy1-f178.google.com with SMTP id 5a478bee46e88-2f00a567cfaso4004119eec.0 for ; Tue, 12 May 2026 16:58:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778630295; x=1779235095; 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=LCJC2OYJjDBPJCpUjZ7QH30Gry2bxV2/GyYziaCQI5w=; b=qTcD5QV5OfNPMQu2/RO4AtycST+psYE4otZtH1GOdIAmYk07JpxC/hRDQXJZ6DLEHq bFvhWc/GKASvjcUga2RavtIQLD3xG+BbRNe8U4JJvcXb4RG1Td0MiqPfoe3sU6TQP9MH uN+rsBoulSgas9ZU/wzlPW3XQXh5OPkPQqyd0c0WmN9V8UGA5ayO4+WeVb1BFKjt5H2V KQeIlJABM+ThpfgHLLvID+99nQbL0R5dP2gICkt3nc/2JScOVMwqvPNWLpObsr4yHXH+ WnHp9melEpdA+uZFbDcSDS4i3/CMU39wKpcuLd14f1+zrtX9ku6tFU35PgXojEo+Vr7Y 9ECA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778630295; x=1779235095; 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=LCJC2OYJjDBPJCpUjZ7QH30Gry2bxV2/GyYziaCQI5w=; b=WGO9jAPQbJYdRKKOouX8JjRpMHmzaBjFEB0f2VpE1v+rhWllD2Z6/OgI2w1VvvPs2Q O4kMv+Z26CdtEX0rUd/gHvC0QvZT1wbeBRmmr816dTgptdgQDT1mYmK/iuC849dVn5Cd Rjh62bHk3ucy8aTa7Uu7BrsCgoWYbxoBGzv4TQp3wIVuKpJwS0Nqnj5ndoterPRO1AUk L7p+HfT/mrugj+YcPXuRXkucMknkS9QikgZ+Ds9vU2Gp4ThGxgWSLIMD6hc5vemm5/yf 20FfYmzxowi50vaHN4IjQy52f6Ab7VFBKBoasNKzjMqEfkrfBaGjJcavdPYckrPG4JhV oxMQ== X-Forwarded-Encrypted: i=1; AFNElJ8NBfnCTIIJ1I1exU37c0Fh5PziXlyGe2/NJLTMTb+hBeQLdv49OvObKlGn83sYCrk2ksRbwpvfpYNgJ7c=@vger.kernel.org X-Gm-Message-State: AOJu0YyvbETFCtD8/9fBFLBguyTlOeoTKd6ValzX9aDBGOWpN9vzKU+S DbXEpdx8Nzk686Y9P8j6VRKmSrdxaOS0czBdy9QvwK9WM4Bi9X0WYAM9 X-Gm-Gg: Acq92OG7BEfoSXgp4zs8D01he+1Ap3RT9c5wgD6JAerNfzaq7/cHhh2+fHMsPzOG/gG AbS9MW/XwQPwE5RzotL2nUYe3X9ih+HoeUPwqxLeeD7WYeOVl8faeuELZ/Dcz3hrcrB5TC/zIS0 OzityHLpwDktIjQ4i3mG2Owhw/6ulje+AU9YiX1VzkPtrdrk4d/I5yLHFMOzXjOqcZasr6Hd4Lr QExbMPopXBD+o45re++qgT5DcFN6SW2Ykv/5lVyY2pXBNyj5bi/GtxhueCMFXPBUMGZkJrhBAw0 uKuoCh10RWN1Fg4WrMJPcDsyCWf5yIlkQShg2ZSvXP9976xEL4hAo4CTnm7SU1dDkQUyz8Lye5j 330zhLND3DeET91OCakx9DyKAbC/5OfLB1ehmEeJw/XrJmyiyWY7uWXh3g6LDs7zcVrE9cNPexO o/tRj5mWBwk93pxKOfgndQzXXS6IVOhaFrIXWKxy7DPgS98YwfQUvsRvoeOnI9B6kPJo8v2RTrI Z9zxtTuOLQbpkU= X-Received: by 2002:a05:7301:6096:b0:2d9:1c9d:fc22 with SMTP id 5a478bee46e88-2ff96344cf2mr3376758eec.21.1778630294968; Tue, 12 May 2026 16:58:14 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2f888e3e285sm23625851eec.27.2026.05.12.16.58.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 16:58:14 -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 v13 5/7] platform/x86: lenovo-wmi-other: Add force_load_psy_ext module parameter Date: Tue, 12 May 2026 23:58:06 +0000 Message-ID: <20260512235808.691046-6-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260512235808.691046-1-derekjohn.clark@gmail.com> References: <20260512235808.691046-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. 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 a423bd563291..9d5250d41a3f 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 Fri Jun 12 20:17:23 2026 Received: from mail-dy1-f170.google.com (mail-dy1-f170.google.com [74.125.82.170]) (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 89EC1383985 for ; Tue, 12 May 2026 23:58:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630298; cv=none; b=k6hlWV93TOo4zy8SKrfy+D5UfsnIjv3R46nGmUmIR+YCnEDGSkI/aEBo4qttVr+4cr4+Jyum/Cj25wTe49ptngT3QCVYyMCU8lH2N4nWEgnf0sOH1IfLIPE7ulko55DNo1SZ0c33NG5fDE5D6sve2eR0Uy9xrgstv6qTQ2FSnFQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630298; c=relaxed/simple; bh=4d42TBYxhrEKUs/Ex72+YVx038OFOO6Efovah/WgVDE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jKqhefzM0xLPbmlpWu2+XdY4eEhK++g8Ufvc08NkKeeAsxG1zFOZUpUGEKmaOBoCrw97hN0qRe7S2VzkKLxZHYOxadXvWPHRmmDMg7Za4jRgbDLvi1jJ+rxscHcPdt9iIGg7p7sfyqZhPZsKCmysRdkQYczosefzt5Qwn/ba19Q= 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=QYGxL6ot; arc=none smtp.client-ip=74.125.82.170 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="QYGxL6ot" Received: by mail-dy1-f170.google.com with SMTP id 5a478bee46e88-2ef8d6ba48bso3634339eec.1 for ; Tue, 12 May 2026 16:58:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778630296; x=1779235096; 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=81SlTE+HhOzFbiYLIxMeZjJ33RF64bMO8xaQDR8dKPg=; b=QYGxL6otiLtlmK447P56IU8e+uvYGajYv18BA2L4uaNUnAKhMUSE/t4980Mr0UtHvT fasEutzWwVveju9C2J5JfxfxOaNqsGGuGfAhh7U+R3cbvytEbGEOBwAleaJP4oxJrW5J XI8x+o9xFbhVlDSYeEwXKVWwpN7MdfhgyVe+NYShHmcxqP7BszNcUKC+/83oPfifJJpe s1FSXp5cqdlHd6F5mOUfDZTlJPaIYSXL7uYEcpPQsqlYcixp+DPsSs9cdvl5aoHN5389 zsUYupWueuRoYzQFz4VQwThB6bQUe6QWRcMzSKNUzgV/NrpswTPkkZbtVEbrXtW4Srgs vYEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778630296; x=1779235096; 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=81SlTE+HhOzFbiYLIxMeZjJ33RF64bMO8xaQDR8dKPg=; b=lnhcTk319JRFONMyrtc4KKKu3jdOvx+sC1WiQlrpZ0x7wd14PvwCuZ+cmOEWwpCeBq zuX0Tb4g15VBH3HOJt6EVXMQgQu4VPXHXr1XL1NVl96oDGF5SjPEv3P1F+Grl//IDmcS b2G6FUfHp6Ls9TI91DIAMZioKSia2gsSfYzCHvONlTApZ5tFg+ieQz+ZDZOYH+R+MMpV tlbpAqEZIw09Ru4wrb25hBwkQhISghs3ZNdAh62CZyRlHA1JI+ypM2qB5sbU1Z5eP6n8 zV4jiIawcx7d6EuDH7oXosw6/DEtzarWHTFsjodueDte2C+LLzQ0CFbmeJ1wi066/zgQ 4UrQ== X-Forwarded-Encrypted: i=1; AFNElJ+w2+KEIpgC8uNc7WyXWN7kYd/uIkCaub2WMNh6qm/IfJ7a20bQyOwA5GafAKiS5nFCmnhSzgJtfU0wT/I=@vger.kernel.org X-Gm-Message-State: AOJu0Yzv8C31LFjNu23i2MPJv2YrRyZ0VYdjKnzfQnnPL/6Y5XUVoKh5 hk+Df5F3wLvUpphyDPXFIyyzNrUTScOr/2k7jGxR9bDqRfD0WQ8tpFNv X-Gm-Gg: Acq92OE8sBmVrRMFBAKsTvfjjbtMtcKDpwE+hZLcrFhZWwIrA1rAYDOAoksBzRC6Hh4 J5FSvcbKx9vrpaf/nOuV4MPKXbvTGfyp/JTncTXSNH1F59Pld0sFjjxpHOTsjmvFWrSg2d8BWuX DU7AaTsKBn7hyM2wMwyXiHkftEgBEHczfbhiCfdbG+XUjH6sQ3YG9PjnQhMArTI2AadkPc8/hjC ADvo7jNPtKOY2yyx1TxuBVkqKG911R+yrCJLSJ0Hij/QM09oTT6GF1gQyMFG+F7UttMm0pl83yi k2BAUay5zLuYYk59Bo+dD+nz6PzP4oN2lJkV2eBQBm1d0Wi7zchE98anNzFJyNLjPbyvwaXOxbP vx88MS9a5Fv3GxkmveTzVQMdNNWOsq+T9vXtwqqI52BOiZFn0HbSA508HuFMhpgo+WcvMylbWZ1 3rEVb409tNvKpAwJ/T65PE6GxKkWFnUiYzyLGNUT1TLqpHME3J5/GqOJLV+PcRkFWFC0r6pTZ3L 4sV X-Received: by 2002:a05:7300:5720:b0:2c1:7480:ff9b with SMTP id 5a478bee46e88-2ff95e5e1cemr2922195eec.18.1778630295708; Tue, 12 May 2026 16:58:15 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2f888e3e285sm23625851eec.27.2026.05.12.16.58.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 16:58:15 -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 v13 6/7] platform/x86: lenovo-wmi-helpers: Add helper for creating per-device debugfs dir Date: Tue, 12 May 2026 23:58:07 +0000 Message-ID: <20260512235808.691046-7-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260512235808.691046-1-derekjohn.clark@gmail.com> References: <20260512235808.691046-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 7a198259e393..8f5766c391eb 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 ed7db3ebba6c..039fe61003ce 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 Fri Jun 12 20:17:23 2026 Received: from mail-dy1-f180.google.com (mail-dy1-f180.google.com [74.125.82.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 698B238E8DC for ; Tue, 12 May 2026 23:58:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630299; cv=none; b=Ohf4L84RKBNf7m0qZ0rS4EdbA24XP05YGeeZkGSSQqNKvJCHOoFkPfjpKI3yuIoLEmw/EpweuaYk6QO2xUKqZAVJJshFRL0bwBh+NQacKItB3/Vik05BYKVC7Sr6v7ZrEr6a7hKVId6F/BHOTtijYSNeDyk/tHX1NHFk7tklex4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778630299; c=relaxed/simple; bh=PMQb3zR86C6B8YYGFksu8QgaO8McJvzRKVARHfl1SVs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d8D7auIjsckUybRQW3v9gR9W/n7HwLUvvSkCFdxRODjuNhA0aDY3DOiTaUn52W61P70cnuHMTHzrmAzXTvPeUoOa+aYFg1DgAzudcYKSQCOTFt2x3E1Cb+QXpEQZSY1kcrENiUtj5oW0rf+6A3R/JerEHvsd15dA2Imy7NBx8uo= 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=k4Yx+iau; arc=none smtp.client-ip=74.125.82.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="k4Yx+iau" Received: by mail-dy1-f180.google.com with SMTP id 5a478bee46e88-2f0ad52830cso9028517eec.1 for ; Tue, 12 May 2026 16:58:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778630297; x=1779235097; 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=UFDEHciNgTBMetNN4oXhJG9zuLjkzYr+k/kwmV3qsh0=; b=k4Yx+iauKyPp7zAlprG0+RvLfn//slb7Wi/e46BtOnixAnNeivx0ATWPqnZWqL/PC8 yWEgdcz9sPhgwCeZlO6gSJBzAHpZPonH5G3iQ8fKpnxNaX1fT+hs6XlWGXB/yNdtKyjT wTlQCIhXr197QTNdhkEDPOaOjjkSovcZdagacODQPsxcmyzx+HvMtHMH1k81YGMZ82wO CkWYaEss/tK45TF2VE5exO30sCvdJWcXjRTFx1rGjYo9CiHr3LZPs8FO9HLk/F/hf+tb ZAXi9ri+IF1GAJyfZoY2noj77l7yxTlTZgJvBjvr0WlBSKvZo1zfTRlL/t1xEr9gRVVs YO2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778630297; x=1779235097; 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=UFDEHciNgTBMetNN4oXhJG9zuLjkzYr+k/kwmV3qsh0=; b=RbeFelSpz0qd/bEREeZGNTYRwOZpfRkrocijw2doSjgFBOTbtXuziVnZykuvCmgKJS PFft7ZybPjbjd775NOS73K3pj7UbK20+bcsbSOsZI8Xq8DrtRBFMHWJ2imgG5Ls2fgRa abA68fctnuUCaQqxQZFUYlZ0Y4FwJmPUjnCDIxo3I8Fcky3QmWA7zvLoA24SmIidE9q0 XSJh2+Wnww+BNymrG/bAcfafSV91lsTTVWfxNMmUiv7lC07LoCDAwho5OmqxOQx+7W6n g2sbecQwlrgoyfduhTKaGKdB8CmtjVeZG8NpM/t/bDJ/PBwQrLmD6++A2qBYe9g3KC/T uW9w== X-Forwarded-Encrypted: i=1; AFNElJ9WUzRXOSked+522O5WF7sGZNsW8Jmic1/CTLE5QVvdrS3VeWF38/7oOT79/Pdc1PfKNaCeQRxdUsejQfc=@vger.kernel.org X-Gm-Message-State: AOJu0YxN456qSDDDgm+sSGpfNAKhOxG/6r86ANUVwInZacNIrV8NLzhw BNQ7u2fkCfk2YNok46eO3fWl9YjpeTmU91JvldzsrB9MNP74WLxk8Y3I X-Gm-Gg: Acq92OHar1riqHG2vXi1a1BUm1idk1N7V+hpWTmwI4yiPCbcvwyGLQttT8bYHrcSyC7 7IbVyrsPyWj5KhuPGf8kUO7Qcp6Jy697LVr2rbj9GFOyv8sDokrAtbi88GHtMhVUzhPeSBndPT2 GS2yysrZbDBrKL9FJjfMJRyCYQuQKpXs1tkRwevVyjDaaNaBSOFSBy10hLMNu1+/OIdCCghm/o9 6uQJ5FEFCelwRgpl+WDKiTJNGeB03JxDjecekQNoAQyj2v0OGk/YCnkVG+gEIy7wEX5BhIf1SFS xvFAO1rPgNq6sRFR1xbgaPypqlee0Kfe6XsoYtw/mk0DgG02mgkstC5ORi1tUpkRaLcHv2KyGif PEBzW+A/CowJW1TdKeVy1ipnoWKIVGdGLVDtKxZMN+JoOJn0nYdwWf6rpW8ECZYgG3EugaTL2Zw LbGsdN53sPOqPWZXlKe9Xt+Wnj508eK3nef22W3BWP4UcPovculuypQyFtKWvI3lBwZBHs0csMl jDL X-Received: by 2002:a05:7301:1292:b0:2ed:e12:376d with SMTP id 5a478bee46e88-3011a468e45mr715170eec.35.1778630296503; Tue, 12 May 2026 16:58:16 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2f888e3e285sm23625851eec.27.2026.05.12.16.58.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 16:58:16 -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 v13 7/7] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Date: Tue, 12 May 2026 23:58:08 +0000 Message-ID: <20260512235808.691046-8-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260512235808.691046-1-derekjohn.clark@gmail.com> References: <20260512235808.691046-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 b9a5d18caa1e..4443f40ef8aa 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 714aa6fd6f1f..d5e961566136 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 a49229cec245..92098aeeee84 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