X86 platform drivers
 help / color / mirror / Atom feed
* [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
@ 2026-02-10 19:19 Rong Zhang
  2026-02-10 19:19 ` [PATCH 1/2] platform/x86: lenovo-wmi-helpers: Add helper for creating per-device debugfs dir Rong Zhang
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Rong Zhang @ 2026-02-10 19:19 UTC (permalink / raw)
  To: Mark Pearson, Derek J. Clark, Armin Wolf, Hans de Goede,
	Ilpo Järvinen
  Cc: Rong Zhang, Kurt Borja, platform-driver-x86, linux-kernel

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/<device_name>/capdata), so that users can
dump capdata and include it in their reports.

The output is like:

  LENOVO_CAPABILITY_DATA_00[0]:
    id:             0x00010000 [dev:  0, feat:  1, mode:  0, type:  0]
    supported:      0x00000007 [ RWV]
    default_value:  0

  LENOVO_CAPABILITY_DATA_01[0]:
    id:             0x00000000 [dev:  0, feat:  0, mode:  0, type:  0]
    supported:      0x00000000 [    ]
    default_value:  0
    step:           0
    min_value:      0
    max_value:      0

  LENOVO_FAN_TEST_DATA[0]:
    id:             1
    min_rpm:        2200
    max_rpm:        5000

A helper function for creating per-devcie debugfs directories is also
introduced into lenovo-wmi-helpers in order that we can maintain a tidy
directory structure in debugfs.

The series is based on platform-drivers-x86/review-ilpo-next since it
depends on a commit there. I am OK to wait until the next cycle.

Rong Zhang (2):
  platform/x86: lenovo-wmi-helpers: Add helper for creating per-device
    debugfs dir
  platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata

 drivers/platform/x86/lenovo/Kconfig       |   1 +
 drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
 drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
 drivers/platform/x86/lenovo/wmi-helpers.c |  34 ++++++
 drivers/platform/x86/lenovo/wmi-helpers.h |   2 +
 5 files changed, 159 insertions(+), 3 deletions(-)


base-commit: 5a5203a45b063a594e89a2aeaf9e4923893a5b4c
-- 
2.51.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/2] platform/x86: lenovo-wmi-helpers: Add helper for creating per-device debugfs dir
  2026-02-10 19:19 [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
@ 2026-02-10 19:19 ` Rong Zhang
  2026-02-10 19:19 ` [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 15+ messages in thread
From: Rong Zhang @ 2026-02-10 19:19 UTC (permalink / raw)
  To: Mark Pearson, Derek J. Clark, Armin Wolf, Hans de Goede,
	Ilpo Järvinen
  Cc: Rong Zhang, Kurt Borja, platform-driver-x86, linux-kernel

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 <i@rong.moe>
---
 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/x86/lenovo/wmi-helpers.c
index 7379defac5002..e615da0d14a18 100644
--- a/drivers/platform/x86/lenovo/wmi-helpers.c
+++ b/drivers/platform/x86/lenovo/wmi-helpers.c
@@ -17,6 +17,8 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
 #include <linux/cleanup.h>
 #include <linux/errno.h>
 #include <linux/export.h>
@@ -84,6 +86,38 @@ int lwmi_dev_evaluate_int(struct wmi_device *wdev, u8 instance, u32 method_id,
 };
 EXPORT_SYMBOL_NS_GPL(lwmi_dev_evaluate_int, "LENOVO_WMI_HELPERS");
 
+static struct dentry *lwmi_debugfs_dir;
+
+/**
+ * lwmi_debugfs_create_dir() - Helper function for creating a debugfs directory
+ * for a device.
+ * @wdev: Pointer to the WMI device to be called.
+ *
+ * Caller must remove the directory with debugfs_remove_recursive() on device
+ * 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 = debugfs_create_dir("lenovo_wmi", NULL);
+
+	return 0;
+}
+module_init(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 <derekjohn.clark@gmail.com>");
 MODULE_DESCRIPTION("Lenovo WMI Helpers Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/lenovo/wmi-helpers.h b/drivers/platform/x86/lenovo/wmi-helpers.h
index 20fd217498035..3df49427567ee 100644
--- a/drivers/platform/x86/lenovo/wmi-helpers.h
+++ b/drivers/platform/x86/lenovo/wmi-helpers.h
@@ -17,4 +17,6 @@ struct wmi_method_args_32 {
 int lwmi_dev_evaluate_int(struct wmi_device *wdev, u8 instance, u32 method_id,
 			  unsigned char *buf, size_t size, u32 *retval);
 
+struct dentry *lwmi_debugfs_create_dir(struct wmi_device *wdev);
+
 #endif /* !_LENOVO_WMI_HELPERS_H_ */
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-10 19:19 [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
  2026-02-10 19:19 ` [PATCH 1/2] platform/x86: lenovo-wmi-helpers: Add helper for creating per-device debugfs dir Rong Zhang
@ 2026-02-10 19:19 ` Rong Zhang
  2026-02-10 20:38   ` Derek J. Clark
  2026-02-25 18:24   ` Kurt Borja
  2026-02-10 23:41 ` [PATCH 0/2] " Kurt Borja
  2026-03-25 18:15 ` Rong Zhang
  3 siblings, 2 replies; 15+ messages in thread
From: Rong Zhang @ 2026-02-10 19:19 UTC (permalink / raw)
  To: Mark Pearson, Derek J. Clark, Armin Wolf, Hans de Goede,
	Ilpo Järvinen
  Cc: Rong Zhang, Kurt Borja, platform-driver-x86, linux-kernel

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/<device_name>/capdata), so that users can
dump capdata and include it in their reports.

Since `struct capdata01' is just an extension to `struct capdata00',
also converts the former to include the latter anonymously
(-fms-extensions, since v6.19). In this manner type casting won't be
confusing.

Signed-off-by: Rong Zhang <i@rong.moe>
---
 drivers/platform/x86/lenovo/Kconfig       |   1 +
 drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
 drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
 3 files changed, 123 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/lenovo/Kconfig
index f885127b007f1..8357971c76d80 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
 
 config LENOVO_WMI_EVENTS
 	tristate
diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
index ee1fb02d8e31e..ca478b45119bc 100644
--- a/drivers/platform/x86/lenovo/wmi-capdata.c
+++ b/drivers/platform/x86/lenovo/wmi-capdata.c
@@ -32,6 +32,7 @@
 #include <linux/cleanup.h>
 #include <linux/component.h>
 #include <linux/container_of.h>
+#include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/dev_printk.h>
 #include <linux/err.h>
@@ -43,11 +44,13 @@
 #include <linux/mutex_types.h>
 #include <linux/notifier.h>
 #include <linux/overflow.h>
+#include <linux/seq_file.h>
 #include <linux/stddef.h>
 #include <linux/types.h>
 #include <linux/wmi.h>
 
 #include "wmi-capdata.h"
+#include "wmi-helpers.h"
 
 #define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E"
 #define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
@@ -88,6 +91,7 @@ struct lwmi_cd_priv {
 	struct notifier_block acpi_nb; /* ACPI events */
 	struct wmi_device *wdev;
 	struct cd_list *list;
+	struct dentry *debugfs_dir;
 
 	/*
 	 * A capdata device may be a component master of another capdata device.
@@ -118,6 +122,8 @@ struct cd_list {
 
 static struct wmi_driver lwmi_cd_driver;
 
+/* ======== Device components ======== */
+
 /**
  * lwmi_cd_match() - Match rule for the master driver.
  * @dev: Pointer to the capability data parent device.
@@ -471,6 +477,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");
 
+/* ======== debugfs ======== */
+
+/**
+ * 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 = FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id);
+	u8 feat = FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id);
+	u8 mode = FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id);
+	u8 type = FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id);
+	bool extra = cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_SUPP_VALID);
+	bool get = cd00->supported & LWMI_SUPP_GET;
+	bool set = cd00->supported & LWMI_SUPP_SET;
+	bool valid = 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, (struct capdata00 *)cd01);
+
+	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_fan)
+{
+	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 = s->private;
+	u8 idx;
+
+	guard(mutex)(&priv->list->list_mutex);
+
+	/* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */
+	for (idx = 0; idx < priv->list->count; idx++) {
+		seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx);
+
+		if (priv->list->type == LENOVO_CAPABILITY_DATA_00)
+			lwmi_cd00_show(s, &priv->list->cd00[idx]);
+		else if (priv->list->type == LENOVO_CAPABILITY_DATA_01)
+			lwmi_cd01_show(s, &priv->list->cd01[idx]);
+		else if (priv->list->type == 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 = lwmi_debugfs_create_dir(priv->wdev);
+
+	debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_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 = NULL;
+}
+
+/* ======== WMI interface ======== */
+
 /**
  * lwmi_cd_cache() - Cache all WMI data block information
  * @priv: lenovo-wmi-capdata driver data.
@@ -773,6 +889,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);
 	}
@@ -783,6 +901,8 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
 {
 	struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev);
 
+	lwmi_cd_debugfs_remove(priv);
+
 	switch (priv->list->type) {
 	case LENOVO_CAPABILITY_DATA_00:
 		lwmi_cd_sub_master_del(priv);
@@ -822,6 +942,7 @@ static struct wmi_driver lwmi_cd_driver = {
 
 module_wmi_driver(lwmi_cd_driver);
 
+MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
 MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table);
 MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
 MODULE_AUTHOR("Rong Zhang <i@rong.moe>");
diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x86/lenovo/wmi-capdata.h
index 8c1df3efcc553..034a6e48be071 100644
--- a/drivers/platform/x86/lenovo/wmi-capdata.h
+++ b/drivers/platform/x86/lenovo/wmi-capdata.h
@@ -30,9 +30,7 @@ struct capdata00 {
 };
 
 struct capdata01 {
-	u32 id;
-	u32 supported;
-	u32 default_value;
+	struct capdata00;
 	u32 step;
 	u32 min_value;
 	u32 max_value;
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-10 19:19 ` [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
@ 2026-02-10 20:38   ` Derek J. Clark
  2026-02-10 23:47     ` Kurt Borja
  2026-02-11 11:47     ` Rong Zhang
  2026-02-25 18:24   ` Kurt Borja
  1 sibling, 2 replies; 15+ messages in thread
From: Derek J. Clark @ 2026-02-10 20:38 UTC (permalink / raw)
  To: Rong Zhang, Mark Pearson, Armin Wolf, Hans de Goede,
	Ilpo Järvinen
  Cc: Kurt Borja, platform-driver-x86, linux-kernel

On February 10, 2026 11:19:37 AM PST, Rong Zhang <i@rong.moe> wrote:
>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/<device_name>/capdata), so that users can
>dump capdata and include it in their reports.
>
>Since `struct capdata01' is just an extension to `struct capdata00',
>also converts the former to include the latter anonymously
>(-fms-extensions, since v6.19). In this manner type casting won't be
>confusing.
>
>Signed-off-by: Rong Zhang <i@rong.moe>
>---
> drivers/platform/x86/lenovo/Kconfig       |   1 +
> drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
> drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
> 3 files changed, 123 insertions(+), 3 deletions(-)
>
>diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/lenovo/Kconfig
>index f885127b007f1..8357971c76d80 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
> 
> config LENOVO_WMI_EVENTS
> 	tristate
>diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
>index ee1fb02d8e31e..ca478b45119bc 100644
>--- a/drivers/platform/x86/lenovo/wmi-capdata.c
>+++ b/drivers/platform/x86/lenovo/wmi-capdata.c
>@@ -32,6 +32,7 @@
> #include <linux/cleanup.h>
> #include <linux/component.h>
> #include <linux/container_of.h>
>+#include <linux/debugfs.h>
> #include <linux/device.h>
> #include <linux/dev_printk.h>
> #include <linux/err.h>
>@@ -43,11 +44,13 @@
> #include <linux/mutex_types.h>
> #include <linux/notifier.h>
> #include <linux/overflow.h>
>+#include <linux/seq_file.h>
> #include <linux/stddef.h>
> #include <linux/types.h>
> #include <linux/wmi.h>
> 
> #include "wmi-capdata.h"
>+#include "wmi-helpers.h"
> 
> #define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E"
> #define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
>@@ -88,6 +91,7 @@ struct lwmi_cd_priv {
> 	struct notifier_block acpi_nb; /* ACPI events */
> 	struct wmi_device *wdev;
> 	struct cd_list *list;
>+	struct dentry *debugfs_dir;
> 
> 	/*
> 	 * A capdata device may be a component master of another capdata device.
>@@ -118,6 +122,8 @@ struct cd_list {
> 
> static struct wmi_driver lwmi_cd_driver;
> 
>+/* ======== Device components ======== */
>+
> /**
>  * lwmi_cd_match() - Match rule for the master driver.
>  * @dev: Pointer to the capability data parent device.
>@@ -471,6 +477,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");
> 
>+/* ======== debugfs ======== */
>+
>+/**
>+ * 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 = FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id);
>+	u8 feat = FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id);
>+	u8 mode = FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id);
>+	u8 type = FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id);
>+	bool extra = cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_SUPP_VALID);
>+	bool get = cd00->supported & LWMI_SUPP_GET;
>+	bool set = cd00->supported & LWMI_SUPP_SET;
>+	bool valid = cd00->supported & LWMI_SUPP_VALID;

Hi Rong,

I have something that will clean this up in the series I'm working on, LWMI_ATTR_ID, that pushes all the FIELD_PREP into a macro. Perhaps it would be worth combining this series into mine that so we can use it here as well. 

My series also addresses some fairly significant bugs, so I'd prefer to not have to wait for this series to get approved to post it as it currently conflicts in other areas.

>+	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, (struct capdata00 *)cd01);
>+
>+	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_fan)
>+{
>+	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 = s->private;
>+	u8 idx;
>+
>+	guard(mutex)(&priv->list->list_mutex);
>+
>+	/* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */
>+	for (idx = 0; idx < priv->list->count; idx++) {
>+		seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx);
>+
>+		if (priv->list->type == LENOVO_CAPABILITY_DATA_00)
>+			lwmi_cd00_show(s, &priv->list->cd00[idx]);
>+		else if (priv->list->type == LENOVO_CAPABILITY_DATA_01)
>+			lwmi_cd01_show(s, &priv->list->cd01[idx]);
>+		else if (priv->list->type == 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 = lwmi_debugfs_create_dir(priv->wdev);
>+
>+	debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_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 = NULL;
>+}
>+
>+/* ======== WMI interface ======== */
>+
> /**
>  * lwmi_cd_cache() - Cache all WMI data block information
>  * @priv: lenovo-wmi-capdata driver data.
>@@ -773,6 +889,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);
> 	}
>@@ -783,6 +901,8 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
> {
> 	struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev);
> 
>+	lwmi_cd_debugfs_remove(priv);
>+
> 	switch (priv->list->type) {
> 	case LENOVO_CAPABILITY_DATA_00:
> 		lwmi_cd_sub_master_del(priv);
>@@ -822,6 +942,7 @@ static struct wmi_driver lwmi_cd_driver = {
> 
> module_wmi_driver(lwmi_cd_driver);
> 
>+MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
> MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table);
> MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
> MODULE_AUTHOR("Rong Zhang <i@rong.moe>");
>diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x86/lenovo/wmi-capdata.h
>index 8c1df3efcc553..034a6e48be071 100644
>--- a/drivers/platform/x86/lenovo/wmi-capdata.h
>+++ b/drivers/platform/x86/lenovo/wmi-capdata.h
>@@ -30,9 +30,7 @@ struct capdata00 {
> };
> 
> struct capdata01 {
>-	u32 id;
>-	u32 supported;
>-	u32 default_value;
>+	struct capdata00;

Doesn't this also require some significant changes to the usage in wmi-other and in the query function? We're accessing these members directly.

Thanks, 
Derek

> 	u32 step;
> 	u32 min_value;
> 	u32 max_value;


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-10 19:19 [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
  2026-02-10 19:19 ` [PATCH 1/2] platform/x86: lenovo-wmi-helpers: Add helper for creating per-device debugfs dir Rong Zhang
  2026-02-10 19:19 ` [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
@ 2026-02-10 23:41 ` Kurt Borja
  2026-02-10 23:49   ` Derek J. Clark
  2026-03-25 18:15 ` Rong Zhang
  3 siblings, 1 reply; 15+ messages in thread
From: Kurt Borja @ 2026-02-10 23:41 UTC (permalink / raw)
  To: Rong Zhang, Mark Pearson, Derek J. Clark, Armin Wolf,
	Hans de Goede, Ilpo Järvinen
  Cc: Kurt Borja, platform-driver-x86, linux-kernel

On Tue Feb 10, 2026 at 2:19 PM -05, Rong Zhang wrote:
> 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/<device_name>/capdata), so that users can
> dump capdata and include it in their reports.
>
> The output is like:
>
>   LENOVO_CAPABILITY_DATA_00[0]:
>     id:             0x00010000 [dev:  0, feat:  1, mode:  0, type:  0]
>     supported:      0x00000007 [ RWV]
>     default_value:  0
>
>   LENOVO_CAPABILITY_DATA_01[0]:
>     id:             0x00000000 [dev:  0, feat:  0, mode:  0, type:  0]
>     supported:      0x00000000 [    ]
>     default_value:  0
>     step:           0
>     min_value:      0
>     max_value:      0
>
>   LENOVO_FAN_TEST_DATA[0]:
>     id:             1
>     min_rpm:        2200
>     max_rpm:        5000
>
> A helper function for creating per-devcie debugfs directories is also
> introduced into lenovo-wmi-helpers in order that we can maintain a tidy
> directory structure in debugfs.
>
> The series is based on platform-drivers-x86/review-ilpo-next since it
> depends on a commit there. I am OK to wait until the next cycle.
>
> Rong Zhang (2):
>   platform/x86: lenovo-wmi-helpers: Add helper for creating per-device
>     debugfs dir
>   platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
>
>  drivers/platform/x86/lenovo/Kconfig       |   1 +
>  drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
>  drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
>  drivers/platform/x86/lenovo/wmi-helpers.c |  34 ++++++
>  drivers/platform/x86/lenovo/wmi-helpers.h |   2 +
>  5 files changed, 159 insertions(+), 3 deletions(-)
>
>
> base-commit: 5a5203a45b063a594e89a2aeaf9e4923893a5b4c

Hi Rong,

This is indeed very useful debug information.

Once you and Derek agree on the approach for this series, I'll add my
Tested-by tag.

One more thing though. Can you please explain the "supported" byte? What
is `+` and `V` supposed to mean?

-- 
Thanks,
 ~ Kurt

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-10 20:38   ` Derek J. Clark
@ 2026-02-10 23:47     ` Kurt Borja
  2026-02-11 11:47     ` Rong Zhang
  1 sibling, 0 replies; 15+ messages in thread
From: Kurt Borja @ 2026-02-10 23:47 UTC (permalink / raw)
  To: Derek J. Clark, Rong Zhang, Mark Pearson, Armin Wolf,
	Hans de Goede, Ilpo Järvinen
  Cc: Kurt Borja, platform-driver-x86, linux-kernel

On Tue Feb 10, 2026 at 3:38 PM -05, Derek J. Clark wrote:
> On February 10, 2026 11:19:37 AM PST, Rong Zhang <i@rong.moe> wrote:
>>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/<device_name>/capdata), so that users can
>>dump capdata and include it in their reports.
>>
>>Since `struct capdata01' is just an extension to `struct capdata00',
>>also converts the former to include the latter anonymously
>>(-fms-extensions, since v6.19). In this manner type casting won't be
>>confusing.
>>
>>Signed-off-by: Rong Zhang <i@rong.moe>
>>---
>> drivers/platform/x86/lenovo/Kconfig       |   1 +
>> drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
>> drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
>> 3 files changed, 123 insertions(+), 3 deletions(-)
>>
>>diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/lenovo/Kconfig
>>index f885127b007f1..8357971c76d80 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
>> 
>> config LENOVO_WMI_EVENTS
>> 	tristate
>>diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
>>index ee1fb02d8e31e..ca478b45119bc 100644
>>--- a/drivers/platform/x86/lenovo/wmi-capdata.c
>>+++ b/drivers/platform/x86/lenovo/wmi-capdata.c
>>@@ -32,6 +32,7 @@
>> #include <linux/cleanup.h>
>> #include <linux/component.h>
>> #include <linux/container_of.h>
>>+#include <linux/debugfs.h>
>> #include <linux/device.h>
>> #include <linux/dev_printk.h>
>> #include <linux/err.h>
>>@@ -43,11 +44,13 @@
>> #include <linux/mutex_types.h>
>> #include <linux/notifier.h>
>> #include <linux/overflow.h>
>>+#include <linux/seq_file.h>
>> #include <linux/stddef.h>
>> #include <linux/types.h>
>> #include <linux/wmi.h>
>> 
>> #include "wmi-capdata.h"
>>+#include "wmi-helpers.h"
>> 
>> #define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E"
>> #define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
>>@@ -88,6 +91,7 @@ struct lwmi_cd_priv {
>> 	struct notifier_block acpi_nb; /* ACPI events */
>> 	struct wmi_device *wdev;
>> 	struct cd_list *list;
>>+	struct dentry *debugfs_dir;
>> 
>> 	/*
>> 	 * A capdata device may be a component master of another capdata device.
>>@@ -118,6 +122,8 @@ struct cd_list {
>> 
>> static struct wmi_driver lwmi_cd_driver;
>> 
>>+/* ======== Device components ======== */
>>+
>> /**
>>  * lwmi_cd_match() - Match rule for the master driver.
>>  * @dev: Pointer to the capability data parent device.
>>@@ -471,6 +477,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");
>> 
>>+/* ======== debugfs ======== */
>>+
>>+/**
>>+ * 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 = FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id);
>>+	u8 feat = FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id);
>>+	u8 mode = FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id);
>>+	u8 type = FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id);
>>+	bool extra = cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_SUPP_VALID);
>>+	bool get = cd00->supported & LWMI_SUPP_GET;
>>+	bool set = cd00->supported & LWMI_SUPP_SET;
>>+	bool valid = cd00->supported & LWMI_SUPP_VALID;
>
> Hi Rong,
>
> I have something that will clean this up in the series I'm working on, LWMI_ATTR_ID, that pushes all the FIELD_PREP into a macro. Perhaps it would be worth combining this series into mine that so we can use it here as well. 
>
> My series also addresses some fairly significant bugs, so I'd prefer to not have to wait for this series to get approved to post it as it currently conflicts in other areas.
>
>>+	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, (struct capdata00 *)cd01);
>>+
>>+	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_fan)
>>+{
>>+	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 = s->private;
>>+	u8 idx;
>>+
>>+	guard(mutex)(&priv->list->list_mutex);
>>+
>>+	/* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */
>>+	for (idx = 0; idx < priv->list->count; idx++) {
>>+		seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx);
>>+
>>+		if (priv->list->type == LENOVO_CAPABILITY_DATA_00)
>>+			lwmi_cd00_show(s, &priv->list->cd00[idx]);
>>+		else if (priv->list->type == LENOVO_CAPABILITY_DATA_01)
>>+			lwmi_cd01_show(s, &priv->list->cd01[idx]);
>>+		else if (priv->list->type == 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 = lwmi_debugfs_create_dir(priv->wdev);
>>+
>>+	debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_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 = NULL;
>>+}
>>+
>>+/* ======== WMI interface ======== */
>>+
>> /**
>>  * lwmi_cd_cache() - Cache all WMI data block information
>>  * @priv: lenovo-wmi-capdata driver data.
>>@@ -773,6 +889,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);
>> 	}
>>@@ -783,6 +901,8 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
>> {
>> 	struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev);
>> 
>>+	lwmi_cd_debugfs_remove(priv);
>>+
>> 	switch (priv->list->type) {
>> 	case LENOVO_CAPABILITY_DATA_00:
>> 		lwmi_cd_sub_master_del(priv);
>>@@ -822,6 +942,7 @@ static struct wmi_driver lwmi_cd_driver = {
>> 
>> module_wmi_driver(lwmi_cd_driver);
>> 
>>+MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
>> MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table);
>> MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
>> MODULE_AUTHOR("Rong Zhang <i@rong.moe>");
>>diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x86/lenovo/wmi-capdata.h
>>index 8c1df3efcc553..034a6e48be071 100644
>>--- a/drivers/platform/x86/lenovo/wmi-capdata.h
>>+++ b/drivers/platform/x86/lenovo/wmi-capdata.h
>>@@ -30,9 +30,7 @@ struct capdata00 {
>> };
>> 
>> struct capdata01 {
>>-	u32 id;
>>-	u32 supported;
>>-	u32 default_value;
>>+	struct capdata00;
>
> Doesn't this also require some significant changes to the usage in wmi-other and in the query function? We're accessing these members directly.

Hi Derek,

Recently, the kernel added support for -fms-extensions, which allows
anonymous struct members. These can be accessed directly, as if the
struct was defined in-place, so it doesn't break direct accesses.

-- 
Thanks,
 ~ Kurt

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-10 23:41 ` [PATCH 0/2] " Kurt Borja
@ 2026-02-10 23:49   ` Derek J. Clark
  2026-02-11 11:49     ` Rong Zhang
  0 siblings, 1 reply; 15+ messages in thread
From: Derek J. Clark @ 2026-02-10 23:49 UTC (permalink / raw)
  To: Kurt Borja, Rong Zhang, Mark Pearson, Armin Wolf, Hans de Goede,
	Ilpo Järvinen
  Cc: platform-driver-x86, linux-kernel

On February 10, 2026 3:41:31 PM PST, Kurt Borja <kuurtb@gmail.com> wrote:
>On Tue Feb 10, 2026 at 2:19 PM -05, Rong Zhang wrote:
>> 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/<device_name>/capdata), so that users can
>> dump capdata and include it in their reports.
>>
>> The output is like:
>>
>>   LENOVO_CAPABILITY_DATA_00[0]:
>>     id:             0x00010000 [dev:  0, feat:  1, mode:  0, type:  0]
>>     supported:      0x00000007 [ RWV]
>>     default_value:  0
>>
>>   LENOVO_CAPABILITY_DATA_01[0]:
>>     id:             0x00000000 [dev:  0, feat:  0, mode:  0, type:  0]
>>     supported:      0x00000000 [    ]
>>     default_value:  0
>>     step:           0
>>     min_value:      0
>>     max_value:      0
>>
>>   LENOVO_FAN_TEST_DATA[0]:
>>     id:             1
>>     min_rpm:        2200
>>     max_rpm:        5000
>>
>> A helper function for creating per-devcie debugfs directories is also
>> introduced into lenovo-wmi-helpers in order that we can maintain a tidy
>> directory structure in debugfs.
>>
>> The series is based on platform-drivers-x86/review-ilpo-next since it
>> depends on a commit there. I am OK to wait until the next cycle.
>>
>> Rong Zhang (2):
>>   platform/x86: lenovo-wmi-helpers: Add helper for creating per-device
>>     debugfs dir
>>   platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
>>
>>  drivers/platform/x86/lenovo/Kconfig       |   1 +
>>  drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
>>  drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
>>  drivers/platform/x86/lenovo/wmi-helpers.c |  34 ++++++
>>  drivers/platform/x86/lenovo/wmi-helpers.h |   2 +
>>  5 files changed, 159 insertions(+), 3 deletions(-)
>>
>>
>> base-commit: 5a5203a45b063a594e89a2aeaf9e4923893a5b4c
>
>Hi Rong,
>
>This is indeed very useful debug information.
>
>Once you and Derek agree on the approach for this series, I'll add my
>Tested-by tag.
>
>One more thing though. Can you please explain the "supported" byte? What
>is `+` and `V` supposed to mean?
>

Kurt,

It's enumerated in the patch:

+       seq_printf(s, "  supported:      0x%08x [%c%c%c%c]\n", cd00->supported,
+                  extra ? '+' : ' ',
+                  get   ? 'R' : ' ',
+                  set   ? 'W' : ' ',
+                  valid ? 'V' : ' ');


From the documentation:
uint32 Capability //7:by project 
bit 2:  0: not support SetFeatureValue(),  1: support SetFeatureValue() 
bit 1:  0: not support GetFeatureValue(),  1: support GetFeatureValue()
bit 0:  0: not support feature,  1: support feature 

I don't see any examples of the "extra" bit in the docs.

Thanks,
Derek

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-10 20:38   ` Derek J. Clark
  2026-02-10 23:47     ` Kurt Borja
@ 2026-02-11 11:47     ` Rong Zhang
  2026-02-11 19:10       ` Derek J. Clark
  2026-02-25 18:28       ` Derek J. Clark
  1 sibling, 2 replies; 15+ messages in thread
From: Rong Zhang @ 2026-02-11 11:47 UTC (permalink / raw)
  To: Derek J. Clark
  Cc: Kurt Borja, Mark Pearson, Armin Wolf, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel

Hi Derek,

On Tue, 2026-02-10 at 12:38 -0800, Derek J. Clark wrote:
> On February 10, 2026 11:19:37 AM PST, Rong Zhang <i@rong.moe> wrote:
> > 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/<device_name>/capdata), so that users can
> > dump capdata and include it in their reports.
> > 
> > Since `struct capdata01' is just an extension to `struct capdata00',
> > also converts the former to include the latter anonymously
> > (-fms-extensions, since v6.19). In this manner type casting won't be
> > confusing.
> > 
> > Signed-off-by: Rong Zhang <i@rong.moe>
> > ---
> > drivers/platform/x86/lenovo/Kconfig       |   1 +
> > drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
> > drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
> > 3 files changed, 123 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/lenovo/Kconfig
> > index f885127b007f1..8357971c76d80 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
> > 
> > config LENOVO_WMI_EVENTS
> > 	tristate
> > diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
> > index ee1fb02d8e31e..ca478b45119bc 100644
> > --- a/drivers/platform/x86/lenovo/wmi-capdata.c
> > +++ b/drivers/platform/x86/lenovo/wmi-capdata.c
> > @@ -32,6 +32,7 @@
> > #include <linux/cleanup.h>
> > #include <linux/component.h>
> > #include <linux/container_of.h>
> > +#include <linux/debugfs.h>
> > #include <linux/device.h>
> > #include <linux/dev_printk.h>
> > #include <linux/err.h>
> > @@ -43,11 +44,13 @@
> > #include <linux/mutex_types.h>
> > #include <linux/notifier.h>
> > #include <linux/overflow.h>
> > +#include <linux/seq_file.h>
> > #include <linux/stddef.h>
> > #include <linux/types.h>
> > #include <linux/wmi.h>
> > 
> > #include "wmi-capdata.h"
> > +#include "wmi-helpers.h"
> > 
> > #define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E"
> > #define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
> > @@ -88,6 +91,7 @@ struct lwmi_cd_priv {
> > 	struct notifier_block acpi_nb; /* ACPI events */
> > 	struct wmi_device *wdev;
> > 	struct cd_list *list;
> > +	struct dentry *debugfs_dir;
> > 
> > 	/*
> > 	 * A capdata device may be a component master of another capdata device.
> > @@ -118,6 +122,8 @@ struct cd_list {
> > 
> > static struct wmi_driver lwmi_cd_driver;
> > 
> > +/* ======== Device components ======== */
> > +
> > /**
> >  * lwmi_cd_match() - Match rule for the master driver.
> >  * @dev: Pointer to the capability data parent device.
> > @@ -471,6 +477,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");
> > 
> > +/* ======== debugfs ======== */
> > +
> > +/**
> > + * 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 = FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id);
> > +	u8 feat = FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id);
> > +	u8 mode = FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id);
> > +	u8 type = FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id);
> > +	bool extra = cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_SUPP_VALID);
> > +	bool get = cd00->supported & LWMI_SUPP_GET;
> > +	bool set = cd00->supported & LWMI_SUPP_SET;
> > +	bool valid = cd00->supported & LWMI_SUPP_VALID;
> 
> Hi Rong,
> 
> I have something that will clean this up in the series I'm working on, LWMI_ATTR_ID, that pushes all the FIELD_PREP into a macro. Perhaps it would be worth combining this series into mine that so we can use it here as well. 
> 
> My series also addresses some fairly significant bugs, so I'd prefer to not have to wait for this series to get approved to post it as it currently conflicts in other areas.

Feel free to integrate this series into yours :)

I have zero experience in doing so but I guess git-send-email should
handle the author field well.

> > +	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, (struct capdata00 *)cd01);
> > +
> > +	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_fan)
> > +{
> > +	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 = s->private;
> > +	u8 idx;
> > +
> > +	guard(mutex)(&priv->list->list_mutex);
> > +
> > +	/* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */
> > +	for (idx = 0; idx < priv->list->count; idx++) {
> > +		seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx);
> > +
> > +		if (priv->list->type == LENOVO_CAPABILITY_DATA_00)
> > +			lwmi_cd00_show(s, &priv->list->cd00[idx]);
> > +		else if (priv->list->type == LENOVO_CAPABILITY_DATA_01)
> > +			lwmi_cd01_show(s, &priv->list->cd01[idx]);
> > +		else if (priv->list->type == 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 = lwmi_debugfs_create_dir(priv->wdev);
> > +
> > +	debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_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 = NULL;
> > +}
> > +
> > +/* ======== WMI interface ======== */
> > +
> > /**
> >  * lwmi_cd_cache() - Cache all WMI data block information
> >  * @priv: lenovo-wmi-capdata driver data.
> > @@ -773,6 +889,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);
> > 	}
> > @@ -783,6 +901,8 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
> > {
> > 	struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev);
> > 
> > +	lwmi_cd_debugfs_remove(priv);
> > +
> > 	switch (priv->list->type) {
> > 	case LENOVO_CAPABILITY_DATA_00:
> > 		lwmi_cd_sub_master_del(priv);
> > @@ -822,6 +942,7 @@ static struct wmi_driver lwmi_cd_driver = {
> > 
> > module_wmi_driver(lwmi_cd_driver);
> > 
> > +MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
> > MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table);
> > MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
> > MODULE_AUTHOR("Rong Zhang <i@rong.moe>");
> > diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x86/lenovo/wmi-capdata.h
> > index 8c1df3efcc553..034a6e48be071 100644
> > --- a/drivers/platform/x86/lenovo/wmi-capdata.h
> > +++ b/drivers/platform/x86/lenovo/wmi-capdata.h
> > @@ -30,9 +30,7 @@ struct capdata00 {
> > };
> > 
> > struct capdata01 {
> > -	u32 id;
> > -	u32 supported;
> > -	u32 default_value;
> > +	struct capdata00;
> 
> Doesn't this also require some significant changes to the usage in wmi-other and in the query function? We're accessing these members directly.

No. As Kurt said, it utilizes a relatively new (since v6.19-rc1) change
to kbuild. See commit c4781dc3d1cf ("Kbuild: enable -fms-extensions").

Thanks,
Rong

> Thanks, 
> Derek
> 
> > 	u32 step;
> > 	u32 min_value;
> > 	u32 max_value;

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-10 23:49   ` Derek J. Clark
@ 2026-02-11 11:49     ` Rong Zhang
  2026-02-11 19:14       ` Derek J. Clark
  0 siblings, 1 reply; 15+ messages in thread
From: Rong Zhang @ 2026-02-11 11:49 UTC (permalink / raw)
  To: Derek J. Clark, Kurt Borja
  Cc: Mark Pearson, Armin Wolf, Hans de Goede, Ilpo Järvinen,
	platform-driver-x86, linux-kernel

Hi Derek and Kurt,

On Tue, 2026-02-10 at 15:49 -0800, Derek J. Clark wrote:
> On February 10, 2026 3:41:31 PM PST, Kurt Borja <kuurtb@gmail.com> wrote:
> > On Tue Feb 10, 2026 at 2:19 PM -05, Rong Zhang wrote:
> > > 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/<device_name>/capdata), so that users can
> > > dump capdata and include it in their reports.
> > > 
> > > The output is like:
> > > 
> > >   LENOVO_CAPABILITY_DATA_00[0]:
> > >     id:             0x00010000 [dev:  0, feat:  1, mode:  0, type:  0]
> > >     supported:      0x00000007 [ RWV]
> > >     default_value:  0
> > > 
> > >   LENOVO_CAPABILITY_DATA_01[0]:
> > >     id:             0x00000000 [dev:  0, feat:  0, mode:  0, type:  0]
> > >     supported:      0x00000000 [    ]
> > >     default_value:  0
> > >     step:           0
> > >     min_value:      0
> > >     max_value:      0
> > > 
> > >   LENOVO_FAN_TEST_DATA[0]:
> > >     id:             1
> > >     min_rpm:        2200
> > >     max_rpm:        5000
> > > 
> > > A helper function for creating per-devcie debugfs directories is also
> > > introduced into lenovo-wmi-helpers in order that we can maintain a tidy
> > > directory structure in debugfs.
> > > 
> > > The series is based on platform-drivers-x86/review-ilpo-next since it
> > > depends on a commit there. I am OK to wait until the next cycle.
> > > 
> > > Rong Zhang (2):
> > >   platform/x86: lenovo-wmi-helpers: Add helper for creating per-device
> > >     debugfs dir
> > >   platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
> > > 
> > >  drivers/platform/x86/lenovo/Kconfig       |   1 +
> > >  drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
> > >  drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
> > >  drivers/platform/x86/lenovo/wmi-helpers.c |  34 ++++++
> > >  drivers/platform/x86/lenovo/wmi-helpers.h |   2 +
> > >  5 files changed, 159 insertions(+), 3 deletions(-)
> > > 
> > > 
> > > base-commit: 5a5203a45b063a594e89a2aeaf9e4923893a5b4c
> > 
> > Hi Rong,
> > 
> > This is indeed very useful debug information.
> > 
> > Once you and Derek agree on the approach for this series, I'll add my
> > Tested-by tag.
> > 
> > One more thing though. Can you please explain the "supported" byte? What
> > is `+` and `V` supposed to mean?

"V" means valid. It's consistent with the corresponding macro name.

> Kurt,
> 
> It's enumerated in the patch:
> 
> +       seq_printf(s, "  supported:      0x%08x [%c%c%c%c]\n", cd00->supported,
> +                  extra ? '+' : ' ',
> +                  get   ? 'R' : ' ',
> +                  set   ? 'W' : ' ',
> +                  valid ? 'V' : ' ');
> 
> 
> From the documentation:
> uint32 Capability //7:by project 
> bit 2:  0: not support SetFeatureValue(),  1: support SetFeatureValue() 
> bit 1:  0: not support GetFeatureValue(),  1: support GetFeatureValue()
> bit 0:  0: not support feature,  1: support feature 
> 
> I don't see any examples of the "extra" bit in the docs.

It's not a single bit. Instead, it's printed out when any bit other
than RWV is set. I added this when I recalled the definition of
capability 0x04050000, which has an extra bit defined:

   Fan Test For Diagnostic Software
   uint32 IDs //0x04050000
   uint32 Capability //9:by project
   bit 3: 0: not support LENOVO_FAN_TEST_DATA, 1 support LENOVO_FAN_TEST_DATA
   bit 2: 0: not support SetFeatureValue(), 1: support SetFeatureValue()
   bit 1: 0: not support GetFeatureValue(), 1: support GetFeatureValue()
   bit 0: 0: not support fan test for diagnostic software, 1: support an test for diagnostic software

(from https://lore.kernel.org/r/CAFqHKTkOZUfDb8cGbGnVPCS9wNbOBsiyOk_MkZR-2_Za6ZPMng@mail.gmail.com/ )

I assume extra bits are not standardized, and some (current or future)
capabilities may have multiple extra bits defined. Hence, I simply
named it "+". After all, it's just a reminder for us to check the
documentation (I don't have any, though).

Thanks,
Rong

> Thanks,
> Derek

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-11 11:47     ` Rong Zhang
@ 2026-02-11 19:10       ` Derek J. Clark
  2026-02-25 18:28       ` Derek J. Clark
  1 sibling, 0 replies; 15+ messages in thread
From: Derek J. Clark @ 2026-02-11 19:10 UTC (permalink / raw)
  To: Rong Zhang
  Cc: Kurt Borja, Mark Pearson, Armin Wolf, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel

On February 11, 2026 3:47:03 AM PST, Rong Zhang <i@rong.moe> wrote:
>Hi Derek,
>
>On Tue, 2026-02-10 at 12:38 -0800, Derek J. Clark wrote:
>> On February 10, 2026 11:19:37 AM PST, Rong Zhang <i@rong.moe> wrote:
>> > 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/<device_name>/capdata), so that users can
>> > dump capdata and include it in their reports.
>> > 
>> > Since `struct capdata01' is just an extension to `struct capdata00',
>> > also converts the former to include the latter anonymously
>> > (-fms-extensions, since v6.19). In this manner type casting won't be
>> > confusing.
>> > 
>> > Signed-off-by: Rong Zhang <i@rong.moe>
>> > ---
>> > drivers/platform/x86/lenovo/Kconfig       |   1 +
>> > drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
>> > drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
>> > 3 files changed, 123 insertions(+), 3 deletions(-)
>> > 
>> > diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/lenovo/Kconfig
>> > index f885127b007f1..8357971c76d80 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
>> > 
>> > config LENOVO_WMI_EVENTS
>> > 	tristate
>> > diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
>> > index ee1fb02d8e31e..ca478b45119bc 100644
>> > --- a/drivers/platform/x86/lenovo/wmi-capdata.c
>> > +++ b/drivers/platform/x86/lenovo/wmi-capdata.c
>> > @@ -32,6 +32,7 @@
>> > #include <linux/cleanup.h>
>> > #include <linux/component.h>
>> > #include <linux/container_of.h>
>> > +#include <linux/debugfs.h>
>> > #include <linux/device.h>
>> > #include <linux/dev_printk.h>
>> > #include <linux/err.h>
>> > @@ -43,11 +44,13 @@
>> > #include <linux/mutex_types.h>
>> > #include <linux/notifier.h>
>> > #include <linux/overflow.h>
>> > +#include <linux/seq_file.h>
>> > #include <linux/stddef.h>
>> > #include <linux/types.h>
>> > #include <linux/wmi.h>
>> > 
>> > #include "wmi-capdata.h"
>> > +#include "wmi-helpers.h"
>> > 
>> > #define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E"
>> > #define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
>> > @@ -88,6 +91,7 @@ struct lwmi_cd_priv {
>> > 	struct notifier_block acpi_nb; /* ACPI events */
>> > 	struct wmi_device *wdev;
>> > 	struct cd_list *list;
>> > +	struct dentry *debugfs_dir;
>> > 
>> > 	/*
>> > 	 * A capdata device may be a component master of another capdata device.
>> > @@ -118,6 +122,8 @@ struct cd_list {
>> > 
>> > static struct wmi_driver lwmi_cd_driver;
>> > 
>> > +/* ======== Device components ======== */
>> > +
>> > /**
>> >  * lwmi_cd_match() - Match rule for the master driver.
>> >  * @dev: Pointer to the capability data parent device.
>> > @@ -471,6 +477,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");
>> > 
>> > +/* ======== debugfs ======== */
>> > +
>> > +/**
>> > + * 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 = FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id);
>> > +	u8 feat = FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id);
>> > +	u8 mode = FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id);
>> > +	u8 type = FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id);
>> > +	bool extra = cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_SUPP_VALID);
>> > +	bool get = cd00->supported & LWMI_SUPP_GET;
>> > +	bool set = cd00->supported & LWMI_SUPP_SET;
>> > +	bool valid = cd00->supported & LWMI_SUPP_VALID;
>> 
>> Hi Rong,
>> 
>> I have something that will clean this up in the series I'm working on, LWMI_ATTR_ID, that pushes all the FIELD_PREP into a macro. Perhaps it would be worth combining this series into mine that so we can use it here as well. 
>> 
>> My series also addresses some fairly significant bugs, so I'd prefer to not have to wait for this series to get approved to post it as it currently conflicts in other areas.
>
>Feel free to integrate this series into yours :)
>
>I have zero experience in doing so but I guess git-send-email should
>handle the author field well.

Hi Rong,

That sounds good. I should be able to retain authorship and make my edits as needed. I'll add a CDB tag for myself if I make any significant changes beyond rebase edits, and I'll send them back to you before publishing for your verification directly. Thanks.

>> > +	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, (struct capdata00 *)cd01);
>> > +
>> > +	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_fan)
>> > +{
>> > +	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 = s->private;
>> > +	u8 idx;
>> > +
>> > +	guard(mutex)(&priv->list->list_mutex);
>> > +
>> > +	/* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */
>> > +	for (idx = 0; idx < priv->list->count; idx++) {
>> > +		seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx);
>> > +
>> > +		if (priv->list->type == LENOVO_CAPABILITY_DATA_00)
>> > +			lwmi_cd00_show(s, &priv->list->cd00[idx]);
>> > +		else if (priv->list->type == LENOVO_CAPABILITY_DATA_01)
>> > +			lwmi_cd01_show(s, &priv->list->cd01[idx]);
>> > +		else if (priv->list->type == 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 = lwmi_debugfs_create_dir(priv->wdev);
>> > +
>> > +	debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_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 = NULL;
>> > +}
>> > +
>> > +/* ======== WMI interface ======== */
>> > +
>> > /**
>> >  * lwmi_cd_cache() - Cache all WMI data block information
>> >  * @priv: lenovo-wmi-capdata driver data.
>> > @@ -773,6 +889,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);
>> > 	}
>> > @@ -783,6 +901,8 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
>> > {
>> > 	struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev);
>> > 
>> > +	lwmi_cd_debugfs_remove(priv);
>> > +
>> > 	switch (priv->list->type) {
>> > 	case LENOVO_CAPABILITY_DATA_00:
>> > 		lwmi_cd_sub_master_del(priv);
>> > @@ -822,6 +942,7 @@ static struct wmi_driver lwmi_cd_driver = {
>> > 
>> > module_wmi_driver(lwmi_cd_driver);
>> > 
>> > +MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
>> > MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table);
>> > MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
>> > MODULE_AUTHOR("Rong Zhang <i@rong.moe>");
>> > diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x86/lenovo/wmi-capdata.h
>> > index 8c1df3efcc553..034a6e48be071 100644
>> > --- a/drivers/platform/x86/lenovo/wmi-capdata.h
>> > +++ b/drivers/platform/x86/lenovo/wmi-capdata.h
>> > @@ -30,9 +30,7 @@ struct capdata00 {
>> > };
>> > 
>> > struct capdata01 {
>> > -	u32 id;
>> > -	u32 supported;
>> > -	u32 default_value;
>> > +	struct capdata00;
>> 
>> Doesn't this also require some significant changes to the usage in wmi-other and in the query function? We're accessing these members directly.
>
>No. As Kurt said, it utilizes a relatively new (since v6.19-rc1) change
>to kbuild. See commit c4781dc3d1cf ("Kbuild: enable -fms-extensions").

That's pretty neat. In that case this makes a lot of sense.

Thanks,
Derek

>Thanks,
>Rong
>
>> Thanks, 
>> Derek
>> 
>> > 	u32 step;
>> > 	u32 min_value;
>> > 	u32 max_value;


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-11 11:49     ` Rong Zhang
@ 2026-02-11 19:14       ` Derek J. Clark
  0 siblings, 0 replies; 15+ messages in thread
From: Derek J. Clark @ 2026-02-11 19:14 UTC (permalink / raw)
  To: Rong Zhang, Kurt Borja
  Cc: Mark Pearson, Armin Wolf, Hans de Goede, Ilpo Järvinen,
	platform-driver-x86, linux-kernel

On February 11, 2026 3:49:43 AM PST, Rong Zhang <i@rong.moe> wrote:
>Hi Derek and Kurt,
>
>On Tue, 2026-02-10 at 15:49 -0800, Derek J. Clark wrote:
>> On February 10, 2026 3:41:31 PM PST, Kurt Borja <kuurtb@gmail.com> wrote:
>> > On Tue Feb 10, 2026 at 2:19 PM -05, Rong Zhang wrote:
>> > > 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/<device_name>/capdata), so that users can
>> > > dump capdata and include it in their reports.
>> > > 
>> > > The output is like:
>> > > 
>> > >   LENOVO_CAPABILITY_DATA_00[0]:
>> > >     id:             0x00010000 [dev:  0, feat:  1, mode:  0, type:  0]
>> > >     supported:      0x00000007 [ RWV]
>> > >     default_value:  0
>> > > 
>> > >   LENOVO_CAPABILITY_DATA_01[0]:
>> > >     id:             0x00000000 [dev:  0, feat:  0, mode:  0, type:  0]
>> > >     supported:      0x00000000 [    ]
>> > >     default_value:  0
>> > >     step:           0
>> > >     min_value:      0
>> > >     max_value:      0
>> > > 
>> > >   LENOVO_FAN_TEST_DATA[0]:
>> > >     id:             1
>> > >     min_rpm:        2200
>> > >     max_rpm:        5000
>> > > 
>> > > A helper function for creating per-devcie debugfs directories is also
>> > > introduced into lenovo-wmi-helpers in order that we can maintain a tidy
>> > > directory structure in debugfs.
>> > > 
>> > > The series is based on platform-drivers-x86/review-ilpo-next since it
>> > > depends on a commit there. I am OK to wait until the next cycle.
>> > > 
>> > > Rong Zhang (2):
>> > >   platform/x86: lenovo-wmi-helpers: Add helper for creating per-device
>> > >     debugfs dir
>> > >   platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
>> > > 
>> > >  drivers/platform/x86/lenovo/Kconfig       |   1 +
>> > >  drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
>> > >  drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
>> > >  drivers/platform/x86/lenovo/wmi-helpers.c |  34 ++++++
>> > >  drivers/platform/x86/lenovo/wmi-helpers.h |   2 +
>> > >  5 files changed, 159 insertions(+), 3 deletions(-)
>> > > 
>> > > 
>> > > base-commit: 5a5203a45b063a594e89a2aeaf9e4923893a5b4c
>> > 
>> > Hi Rong,
>> > 
>> > This is indeed very useful debug information.
>> > 
>> > Once you and Derek agree on the approach for this series, I'll add my
>> > Tested-by tag.
>> > 
>> > One more thing though. Can you please explain the "supported" byte? What
>> > is `+` and `V` supposed to mean?
>
>"V" means valid. It's consistent with the corresponding macro name.
>
>> Kurt,
>> 
>> It's enumerated in the patch:
>> 
>> +       seq_printf(s, "  supported:      0x%08x [%c%c%c%c]\n", cd00->supported,
>> +                  extra ? '+' : ' ',
>> +                  get   ? 'R' : ' ',
>> +                  set   ? 'W' : ' ',
>> +                  valid ? 'V' : ' ');
>> 
>> 
>> From the documentation:
>> uint32 Capability //7:by project 
>> bit 2:  0: not support SetFeatureValue(),  1: support SetFeatureValue() 
>> bit 1:  0: not support GetFeatureValue(),  1: support GetFeatureValue()
>> bit 0:  0: not support feature,  1: support feature 
>> 
>> I don't see any examples of the "extra" bit in the docs.
>
>It's not a single bit. Instead, it's printed out when any bit other
>than RWV is set. I added this when I recalled the definition of
>capability 0x04050000, which has an extra bit defined:
>
>   Fan Test For Diagnostic Software
>   uint32 IDs //0x04050000
>   uint32 Capability //9:by project
>   bit 3: 0: not support LENOVO_FAN_TEST_DATA, 1 support LENOVO_FAN_TEST_DATA
>   bit 2: 0: not support SetFeatureValue(), 1: support SetFeatureValue()
>   bit 1: 0: not support GetFeatureValue(), 1: support GetFeatureValue()
>   bit 0: 0: not support fan test for diagnostic software, 1: support an test for diagnostic software
>
>(from https://lore.kernel.org/r/CAFqHKTkOZUfDb8cGbGnVPCS9wNbOBsiyOk_MkZR-2_Za6ZPMng@mail.gmail.com/ )
>
>I assume extra bits are not standardized, and some (current or future)
>capabilities may have multiple extra bits defined. Hence, I simply
>named it "+". After all, it's just a reminder for us to check the
>documentation (I don't have any, though).

Okay. Makes sense. I have no issues with reporting that then. 

Thanks,
Derek

>Thanks,
>Rong
>
>> Thanks,
>> Derek


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-10 19:19 ` [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
  2026-02-10 20:38   ` Derek J. Clark
@ 2026-02-25 18:24   ` Kurt Borja
  1 sibling, 0 replies; 15+ messages in thread
From: Kurt Borja @ 2026-02-25 18:24 UTC (permalink / raw)
  To: Rong Zhang, Mark Pearson, Derek J. Clark, Armin Wolf,
	Hans de Goede, Ilpo Järvinen
  Cc: Kurt Borja, platform-driver-x86, linux-kernel

On Tue Feb 10, 2026 at 2:19 PM -05, Rong Zhang wrote:
> 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/<device_name>/capdata), so that users can
> dump capdata and include it in their reports.
>
> Since `struct capdata01' is just an extension to `struct capdata00',
> also converts the former to include the latter anonymously
> (-fms-extensions, since v6.19). In this manner type casting won't be
> confusing.
>
> Signed-off-by: Rong Zhang <i@rong.moe>

Tested-by: Kurt Borja <kuurtb@gmail.com>

> ---
>  drivers/platform/x86/lenovo/Kconfig       |   1 +
>  drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
>  drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
>  3 files changed, 123 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/lenovo/Kconfig
> index f885127b007f1..8357971c76d80 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
>  
>  config LENOVO_WMI_EVENTS
>  	tristate
> diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
> index ee1fb02d8e31e..ca478b45119bc 100644
> --- a/drivers/platform/x86/lenovo/wmi-capdata.c
> +++ b/drivers/platform/x86/lenovo/wmi-capdata.c
> @@ -32,6 +32,7 @@
>  #include <linux/cleanup.h>
>  #include <linux/component.h>
>  #include <linux/container_of.h>
> +#include <linux/debugfs.h>
>  #include <linux/device.h>
>  #include <linux/dev_printk.h>
>  #include <linux/err.h>
> @@ -43,11 +44,13 @@
>  #include <linux/mutex_types.h>
>  #include <linux/notifier.h>
>  #include <linux/overflow.h>
> +#include <linux/seq_file.h>
>  #include <linux/stddef.h>
>  #include <linux/types.h>
>  #include <linux/wmi.h>
>  
>  #include "wmi-capdata.h"
> +#include "wmi-helpers.h"
>  
>  #define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E"
>  #define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
> @@ -88,6 +91,7 @@ struct lwmi_cd_priv {
>  	struct notifier_block acpi_nb; /* ACPI events */
>  	struct wmi_device *wdev;
>  	struct cd_list *list;
> +	struct dentry *debugfs_dir;
>  
>  	/*
>  	 * A capdata device may be a component master of another capdata device.
> @@ -118,6 +122,8 @@ struct cd_list {
>  
>  static struct wmi_driver lwmi_cd_driver;
>  
> +/* ======== Device components ======== */
> +
>  /**
>   * lwmi_cd_match() - Match rule for the master driver.
>   * @dev: Pointer to the capability data parent device.
> @@ -471,6 +477,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");
>  
> +/* ======== debugfs ======== */
> +
> +/**
> + * 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 = FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id);
> +	u8 feat = FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id);
> +	u8 mode = FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id);
> +	u8 type = FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id);
> +	bool extra = cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_SUPP_VALID);
> +	bool get = cd00->supported & LWMI_SUPP_GET;
> +	bool set = cd00->supported & LWMI_SUPP_SET;
> +	bool valid = 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, (struct capdata00 *)cd01);
> +
> +	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_fan)
> +{
> +	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 = s->private;
> +	u8 idx;
> +
> +	guard(mutex)(&priv->list->list_mutex);
> +
> +	/* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */
> +	for (idx = 0; idx < priv->list->count; idx++) {
> +		seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx);
> +
> +		if (priv->list->type == LENOVO_CAPABILITY_DATA_00)
> +			lwmi_cd00_show(s, &priv->list->cd00[idx]);
> +		else if (priv->list->type == LENOVO_CAPABILITY_DATA_01)
> +			lwmi_cd01_show(s, &priv->list->cd01[idx]);
> +		else if (priv->list->type == 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 = lwmi_debugfs_create_dir(priv->wdev);
> +
> +	debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_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 = NULL;
> +}
> +
> +/* ======== WMI interface ======== */
> +
>  /**
>   * lwmi_cd_cache() - Cache all WMI data block information
>   * @priv: lenovo-wmi-capdata driver data.
> @@ -773,6 +889,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);
>  	}
> @@ -783,6 +901,8 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
>  {
>  	struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev);
>  
> +	lwmi_cd_debugfs_remove(priv);
> +
>  	switch (priv->list->type) {
>  	case LENOVO_CAPABILITY_DATA_00:
>  		lwmi_cd_sub_master_del(priv);
> @@ -822,6 +942,7 @@ static struct wmi_driver lwmi_cd_driver = {
>  
>  module_wmi_driver(lwmi_cd_driver);
>  
> +MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
>  MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table);
>  MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
>  MODULE_AUTHOR("Rong Zhang <i@rong.moe>");
> diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x86/lenovo/wmi-capdata.h
> index 8c1df3efcc553..034a6e48be071 100644
> --- a/drivers/platform/x86/lenovo/wmi-capdata.h
> +++ b/drivers/platform/x86/lenovo/wmi-capdata.h
> @@ -30,9 +30,7 @@ struct capdata00 {
>  };
>  
>  struct capdata01 {
> -	u32 id;
> -	u32 supported;
> -	u32 default_value;
> +	struct capdata00;
>  	u32 step;
>  	u32 min_value;
>  	u32 max_value;


-- 
Thanks,
 ~ Kurt


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-11 11:47     ` Rong Zhang
  2026-02-11 19:10       ` Derek J. Clark
@ 2026-02-25 18:28       ` Derek J. Clark
  1 sibling, 0 replies; 15+ messages in thread
From: Derek J. Clark @ 2026-02-25 18:28 UTC (permalink / raw)
  To: Rong Zhang
  Cc: Kurt Borja, Mark Pearson, Armin Wolf, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel

On February 11, 2026 3:47:03 AM PST, Rong Zhang <i@rong.moe> wrote:
>Hi Derek,
>
>On Tue, 2026-02-10 at 12:38 -0800, Derek J. Clark wrote:
>> On February 10, 2026 11:19:37 AM PST, Rong Zhang <i@rong.moe> wrote:
>> > 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/<device_name>/capdata), so that users can
>> > dump capdata and include it in their reports.
>> > 
>> > Since `struct capdata01' is just an extension to `struct capdata00',
>> > also converts the former to include the latter anonymously
>> > (-fms-extensions, since v6.19). In this manner type casting won't be
>> > confusing.
>> > 
>> > Signed-off-by: Rong Zhang <i@rong.moe>
>> > ---
>> > drivers/platform/x86/lenovo/Kconfig       |   1 +
>> > drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
>> > drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
>> > 3 files changed, 123 insertions(+), 3 deletions(-)
>> > 
>> > diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/lenovo/Kconfig
>> > index f885127b007f1..8357971c76d80 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
>> > 
>> > config LENOVO_WMI_EVENTS
>> > 	tristate
>> > diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
>> > index ee1fb02d8e31e..ca478b45119bc 100644
>> > --- a/drivers/platform/x86/lenovo/wmi-capdata.c
>> > +++ b/drivers/platform/x86/lenovo/wmi-capdata.c
>> > @@ -32,6 +32,7 @@
>> > #include <linux/cleanup.h>
>> > #include <linux/component.h>
>> > #include <linux/container_of.h>
>> > +#include <linux/debugfs.h>
>> > #include <linux/device.h>
>> > #include <linux/dev_printk.h>
>> > #include <linux/err.h>
>> > @@ -43,11 +44,13 @@
>> > #include <linux/mutex_types.h>
>> > #include <linux/notifier.h>
>> > #include <linux/overflow.h>
>> > +#include <linux/seq_file.h>
>> > #include <linux/stddef.h>
>> > #include <linux/types.h>
>> > #include <linux/wmi.h>
>> > 
>> > #include "wmi-capdata.h"
>> > +#include "wmi-helpers.h"
>> > 
>> > #define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E"
>> > #define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
>> > @@ -88,6 +91,7 @@ struct lwmi_cd_priv {
>> > 	struct notifier_block acpi_nb; /* ACPI events */
>> > 	struct wmi_device *wdev;
>> > 	struct cd_list *list;
>> > +	struct dentry *debugfs_dir;
>> > 
>> > 	/*
>> > 	 * A capdata device may be a component master of another capdata device.
>> > @@ -118,6 +122,8 @@ struct cd_list {
>> > 
>> > static struct wmi_driver lwmi_cd_driver;
>> > 
>> > +/* ======== Device components ======== */
>> > +
>> > /**
>> >  * lwmi_cd_match() - Match rule for the master driver.
>> >  * @dev: Pointer to the capability data parent device.
>> > @@ -471,6 +477,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");
>> > 
>> > +/* ======== debugfs ======== */
>> > +
>> > +/**
>> > + * 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 = FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id);
>> > +	u8 feat = FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id);
>> > +	u8 mode = FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id);
>> > +	u8 type = FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id);
>> > +	bool extra = cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_SUPP_VALID);
>> > +	bool get = cd00->supported & LWMI_SUPP_GET;
>> > +	bool set = cd00->supported & LWMI_SUPP_SET;
>> > +	bool valid = cd00->supported & LWMI_SUPP_VALID;
>> 
>> Hi Rong,
>> 
>> I have something that will clean this up in the series I'm working on, LWMI_ATTR_ID, that pushes all the FIELD_PREP into a macro. Perhaps it would be worth combining this series into mine that so we can use it here as well. 
>> 
>> My series also addresses some fairly significant bugs, so I'd prefer to not have to wait for this series to get approved to post it as it currently conflicts in other areas.
>
>Feel free to integrate this series into yours :)
>
>I have zero experience in doing so but I guess git-send-email should
>handle the author field well.
>

Just to follow up in this thread as well, after finding there weren't any conflicts I'm fine with this being an independent series.

Thanks, 
Derek

>> > +	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, (struct capdata00 *)cd01);
>> > +
>> > +	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_fan)
>> > +{
>> > +	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 = s->private;
>> > +	u8 idx;
>> > +
>> > +	guard(mutex)(&priv->list->list_mutex);
>> > +
>> > +	/* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */
>> > +	for (idx = 0; idx < priv->list->count; idx++) {
>> > +		seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx);
>> > +
>> > +		if (priv->list->type == LENOVO_CAPABILITY_DATA_00)
>> > +			lwmi_cd00_show(s, &priv->list->cd00[idx]);
>> > +		else if (priv->list->type == LENOVO_CAPABILITY_DATA_01)
>> > +			lwmi_cd01_show(s, &priv->list->cd01[idx]);
>> > +		else if (priv->list->type == 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 = lwmi_debugfs_create_dir(priv->wdev);
>> > +
>> > +	debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_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 = NULL;
>> > +}
>> > +
>> > +/* ======== WMI interface ======== */
>> > +
>> > /**
>> >  * lwmi_cd_cache() - Cache all WMI data block information
>> >  * @priv: lenovo-wmi-capdata driver data.
>> > @@ -773,6 +889,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);
>> > 	}
>> > @@ -783,6 +901,8 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
>> > {
>> > 	struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev);
>> > 
>> > +	lwmi_cd_debugfs_remove(priv);
>> > +
>> > 	switch (priv->list->type) {
>> > 	case LENOVO_CAPABILITY_DATA_00:
>> > 		lwmi_cd_sub_master_del(priv);
>> > @@ -822,6 +942,7 @@ static struct wmi_driver lwmi_cd_driver = {
>> > 
>> > module_wmi_driver(lwmi_cd_driver);
>> > 
>> > +MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
>> > MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table);
>> > MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
>> > MODULE_AUTHOR("Rong Zhang <i@rong.moe>");
>> > diff --git a/drivers/platform/x86/lenovo/wmi-capdata.h b/drivers/platform/x86/lenovo/wmi-capdata.h
>> > index 8c1df3efcc553..034a6e48be071 100644
>> > --- a/drivers/platform/x86/lenovo/wmi-capdata.h
>> > +++ b/drivers/platform/x86/lenovo/wmi-capdata.h
>> > @@ -30,9 +30,7 @@ struct capdata00 {
>> > };
>> > 
>> > struct capdata01 {
>> > -	u32 id;
>> > -	u32 supported;
>> > -	u32 default_value;
>> > +	struct capdata00;
>> 
>> Doesn't this also require some significant changes to the usage in wmi-other and in the query function? We're accessing these members directly.
>
>No. As Kurt said, it utilizes a relatively new (since v6.19-rc1) change
>to kbuild. See commit c4781dc3d1cf ("Kbuild: enable -fms-extensions").
>
>Thanks,
>Rong
>
>> Thanks, 
>> Derek
>> 
>> > 	u32 step;
>> > 	u32 min_value;
>> > 	u32 max_value;


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-02-10 19:19 [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
                   ` (2 preceding siblings ...)
  2026-02-10 23:41 ` [PATCH 0/2] " Kurt Borja
@ 2026-03-25 18:15 ` Rong Zhang
  2026-03-26 16:34   ` Rong Zhang
  3 siblings, 1 reply; 15+ messages in thread
From: Rong Zhang @ 2026-03-25 18:15 UTC (permalink / raw)
  To: Mark Pearson, Derek J. Clark, Armin Wolf, Hans de Goede,
	Ilpo Järvinen
  Cc: Kurt Borja, platform-driver-x86, linux-kernel

Hi all,

Gentle ping :-)

Thanks,
Rong

On Wed, 2026-02-11 at 03:19 +0800, Rong Zhang wrote:
> 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/<device_name>/capdata), so that users can
> dump capdata and include it in their reports.
> 
> The output is like:
> 
>   LENOVO_CAPABILITY_DATA_00[0]:
>     id:             0x00010000 [dev:  0, feat:  1, mode:  0, type:  0]
>     supported:      0x00000007 [ RWV]
>     default_value:  0
> 
>   LENOVO_CAPABILITY_DATA_01[0]:
>     id:             0x00000000 [dev:  0, feat:  0, mode:  0, type:  0]
>     supported:      0x00000000 [    ]
>     default_value:  0
>     step:           0
>     min_value:      0
>     max_value:      0
> 
>   LENOVO_FAN_TEST_DATA[0]:
>     id:             1
>     min_rpm:        2200
>     max_rpm:        5000
> 
> A helper function for creating per-devcie debugfs directories is also
> introduced into lenovo-wmi-helpers in order that we can maintain a tidy
> directory structure in debugfs.
> 
> The series is based on platform-drivers-x86/review-ilpo-next since it
> depends on a commit there. I am OK to wait until the next cycle.
> 
> Rong Zhang (2):
>   platform/x86: lenovo-wmi-helpers: Add helper for creating per-device
>     debugfs dir
>   platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
> 
>  drivers/platform/x86/lenovo/Kconfig       |   1 +
>  drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
>  drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
>  drivers/platform/x86/lenovo/wmi-helpers.c |  34 ++++++
>  drivers/platform/x86/lenovo/wmi-helpers.h |   2 +
>  5 files changed, 159 insertions(+), 3 deletions(-)
> 
> 
> base-commit: 5a5203a45b063a594e89a2aeaf9e4923893a5b4c

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
  2026-03-25 18:15 ` Rong Zhang
@ 2026-03-26 16:34   ` Rong Zhang
  0 siblings, 0 replies; 15+ messages in thread
From: Rong Zhang @ 2026-03-26 16:34 UTC (permalink / raw)
  To: Mark Pearson, Derek J. Clark, Armin Wolf, Hans de Goede,
	Ilpo Järvinen
  Cc: Kurt Borja, platform-driver-x86, linux-kernel

Hi all,

On Thu, 2026-03-26 at 02:15 +0800, Rong Zhang wrote:
> Hi all,
> 
> Gentle ping :-)

Sorry for disturbing.

This series will be integrated into Derek's series as they will
conflict once the latter adopts another fix patch.

See the discussion at
https://lore.kernel.org/r/861d0276a759461be446df8e996d196037c9b581.camel@rong.moe/

The fix patch is
https://lore.kernel.org/r/20260326161724.72186-1-i@rong.moe/

Thanks,
Rong

> 
> Thanks,
> Rong
> 
> On Wed, 2026-02-11 at 03:19 +0800, Rong Zhang wrote:
> > 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/<device_name>/capdata), so that users can
> > dump capdata and include it in their reports.
> > 
> > The output is like:
> > 
> >   LENOVO_CAPABILITY_DATA_00[0]:
> >     id:             0x00010000 [dev:  0, feat:  1, mode:  0, type:  0]
> >     supported:      0x00000007 [ RWV]
> >     default_value:  0
> > 
> >   LENOVO_CAPABILITY_DATA_01[0]:
> >     id:             0x00000000 [dev:  0, feat:  0, mode:  0, type:  0]
> >     supported:      0x00000000 [    ]
> >     default_value:  0
> >     step:           0
> >     min_value:      0
> >     max_value:      0
> > 
> >   LENOVO_FAN_TEST_DATA[0]:
> >     id:             1
> >     min_rpm:        2200
> >     max_rpm:        5000
> > 
> > A helper function for creating per-devcie debugfs directories is also
> > introduced into lenovo-wmi-helpers in order that we can maintain a tidy
> > directory structure in debugfs.
> > 
> > The series is based on platform-drivers-x86/review-ilpo-next since it
> > depends on a commit there. I am OK to wait until the next cycle.
> > 
> > Rong Zhang (2):
> >   platform/x86: lenovo-wmi-helpers: Add helper for creating per-device
> >     debugfs dir
> >   platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata
> > 
> >  drivers/platform/x86/lenovo/Kconfig       |   1 +
> >  drivers/platform/x86/lenovo/wmi-capdata.c | 121 ++++++++++++++++++++++
> >  drivers/platform/x86/lenovo/wmi-capdata.h |   4 +-
> >  drivers/platform/x86/lenovo/wmi-helpers.c |  34 ++++++
> >  drivers/platform/x86/lenovo/wmi-helpers.h |   2 +
> >  5 files changed, 159 insertions(+), 3 deletions(-)
> > 
> > 
> > base-commit: 5a5203a45b063a594e89a2aeaf9e4923893a5b4c

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-03-26 16:39 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-10 19:19 [PATCH 0/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
2026-02-10 19:19 ` [PATCH 1/2] platform/x86: lenovo-wmi-helpers: Add helper for creating per-device debugfs dir Rong Zhang
2026-02-10 19:19 ` [PATCH 2/2] platform/x86: lenovo-wmi-capdata: Add debugfs file for dumping capdata Rong Zhang
2026-02-10 20:38   ` Derek J. Clark
2026-02-10 23:47     ` Kurt Borja
2026-02-11 11:47     ` Rong Zhang
2026-02-11 19:10       ` Derek J. Clark
2026-02-25 18:28       ` Derek J. Clark
2026-02-25 18:24   ` Kurt Borja
2026-02-10 23:41 ` [PATCH 0/2] " Kurt Borja
2026-02-10 23:49   ` Derek J. Clark
2026-02-11 11:49     ` Rong Zhang
2026-02-11 19:14       ` Derek J. Clark
2026-03-25 18:15 ` Rong Zhang
2026-03-26 16:34   ` Rong Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox