[PATCH 2/9] platform/x86: lenovo-wmi-capdata: Store a pointer to component info
From: Rong Zhang
Date: Sun Sep 13 2026 - 16:51:28 EST
In the following changes, priv->list will become optional (i.e.,
NULLable). IOW, the type of the component cannot be reliable retrieved
from priv->list->type.
Store a pointer to component info so that the component type is always
available. In this manner, priv->list->type can be eliminated. Note that
the component type check in lwmi_cd*_get_data() must be removed due to
it being called without the availability of priv. Removing it should be
fine as the capdata APIs are really internal methods and their caller,
i.e., lenovo-wmi-other, always passes a matched list.
This also eliminates the need to pass the component type along setup
functions.
Signed-off-by: Rong Zhang <i@xxxxxxxx>
---
drivers/platform/x86/lenovo/wmi-capdata.c | 44 +++++++++++++------------------
1 file changed, 19 insertions(+), 25 deletions(-)
diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
index c9e4380a70d2..880ac444c206 100644
--- a/drivers/platform/x86/lenovo/wmi-capdata.c
+++ b/drivers/platform/x86/lenovo/wmi-capdata.c
@@ -87,6 +87,7 @@ static const struct lwmi_cd_info {
struct lwmi_cd_priv {
struct notifier_block acpi_nb; /* ACPI events */
+ const struct lwmi_cd_info *info;
struct wmi_device *wdev;
struct cd_list *list;
struct dentry *debugfs_dir;
@@ -110,7 +111,6 @@ struct lwmi_cd_priv {
struct cd_list {
struct mutex list_mutex; /* list R/W mutex */
- enum lwmi_cd_type type;
u8 count;
union {
@@ -139,7 +139,7 @@ static int lwmi_cd_match(struct device *dev, void *type)
return false;
priv = dev_get_drvdata(dev);
- return priv->list->type == *(enum lwmi_cd_type *)type;
+ return priv->info->type == *(enum lwmi_cd_type *)type;
}
/**
@@ -256,7 +256,7 @@ static int lwmi_cd_component_bind(struct device *cd_dev,
struct lwmi_cd_priv *priv = dev_get_drvdata(cd_dev);
struct lwmi_cd_binder *binder = data;
- switch (priv->list->type) {
+ switch (priv->info->type) {
case LENOVO_CAPABILITY_DATA_00:
binder->cd00_list = priv->list;
@@ -454,14 +454,11 @@ static const struct component_ops lwmi_cd_sub_component_ops = {
*
* Return: 0 on success, or -EINVAL.
*/
-#define DEF_LWMI_CDXX_GET_DATA(_cdxx, _cd_type, _output_t) \
+#define DEF_LWMI_CDXX_GET_DATA(_cdxx, _output_t) \
int lwmi_##_cdxx##_get_data(struct cd_list *list, u32 attribute_id, _output_t *output) \
{ \
u8 idx; \
\
- if (WARN_ON(list->type != _cd_type)) \
- return -EINVAL; \
- \
guard(mutex)(&list->list_mutex); \
for (idx = 0; idx < list->count; idx++) { \
if (list->_cdxx[idx].id != attribute_id) \
@@ -472,13 +469,13 @@ static const struct component_ops lwmi_cd_sub_component_ops = {
return -EINVAL; \
}
-DEF_LWMI_CDXX_GET_DATA(cd00, LENOVO_CAPABILITY_DATA_00, struct capdata00);
+DEF_LWMI_CDXX_GET_DATA(cd00, struct capdata00);
EXPORT_SYMBOL_NS_GPL(lwmi_cd00_get_data, "LENOVO_WMI_CAPDATA");
-DEF_LWMI_CDXX_GET_DATA(cd01, LENOVO_CAPABILITY_DATA_01, struct capdata01);
+DEF_LWMI_CDXX_GET_DATA(cd01, struct capdata01);
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);
+DEF_LWMI_CDXX_GET_DATA(cd_fan, struct capdata_fan);
EXPORT_SYMBOL_NS_GPL(lwmi_cd_fan_get_data, "LENOVO_WMI_CAPDATA");
/* ======== debugfs ======== */
@@ -552,15 +549,14 @@ static int lwmi_cd_debugfs_show(struct seq_file *s, void *data)
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);
+ seq_printf(s, "%s[%u]:\n", priv->info->name, idx);
- if (priv->list->type == LENOVO_CAPABILITY_DATA_00)
+ if (priv->info->type == LENOVO_CAPABILITY_DATA_00)
lwmi_cd00_show(s, &priv->list->cd00[idx]);
- else if (priv->list->type == LENOVO_CAPABILITY_DATA_01)
+ else if (priv->info->type == LENOVO_CAPABILITY_DATA_01)
lwmi_cd01_show(s, &priv->list->cd01[idx]);
- else if (priv->list->type == LENOVO_FAN_TEST_DATA)
+ else if (priv->info->type == LENOVO_FAN_TEST_DATA)
lwmi_cd_fan_show(s, &priv->list->cd_fan[idx]);
}
@@ -605,7 +601,7 @@ static int lwmi_cd_cache(struct lwmi_cd_priv *priv)
int idx;
void *p;
- switch (priv->list->type) {
+ switch (priv->info->type) {
case LENOVO_CAPABILITY_DATA_00:
p = &priv->list->cd00[0];
size = sizeof(priv->list->cd00[0]);
@@ -708,14 +704,13 @@ static int lwmi_cd_fan_list_alloc_cache(struct lwmi_cd_priv *priv, struct cd_lis
/**
* lwmi_cd_alloc() - Allocate a cd_list struct in drvdata
* @priv: lenovo-wmi-capdata driver data.
- * @type: The type of capability data.
*
* Allocate a cd_list struct large enough to contain data from all WMI data
* blocks provided by the interface.
*
* Return: 0 on success, or an error.
*/
-static int lwmi_cd_alloc(struct lwmi_cd_priv *priv, enum lwmi_cd_type type)
+static int lwmi_cd_alloc(struct lwmi_cd_priv *priv)
{
struct cd_list *list;
size_t list_size;
@@ -723,7 +718,7 @@ static int lwmi_cd_alloc(struct lwmi_cd_priv *priv, enum lwmi_cd_type type)
count = wmidev_instance_count(priv->wdev);
- switch (type) {
+ switch (priv->info->type) {
case LENOVO_CAPABILITY_DATA_00:
list_size = struct_size(list, cd00, count);
break;
@@ -749,7 +744,6 @@ static int lwmi_cd_alloc(struct lwmi_cd_priv *priv, enum lwmi_cd_type type)
if (ret)
return ret;
- list->type = type;
list->count = count;
priv->list = list;
@@ -759,7 +753,6 @@ static int lwmi_cd_alloc(struct lwmi_cd_priv *priv, enum lwmi_cd_type type)
/**
* lwmi_cd_setup() - Cache all WMI data block information
* @priv: lenovo-wmi-capdata driver data.
- * @type: The type of capability data.
*
* Allocate a cd_list struct large enough to contain data from all WMI data
* blocks provided by the interface. Then loop through each data block and
@@ -767,11 +760,11 @@ static int lwmi_cd_alloc(struct lwmi_cd_priv *priv, enum lwmi_cd_type type)
*
* Return: 0 on success, or an error code.
*/
-static int lwmi_cd_setup(struct lwmi_cd_priv *priv, enum lwmi_cd_type type)
+static int lwmi_cd_setup(struct lwmi_cd_priv *priv)
{
int ret;
- ret = lwmi_cd_alloc(priv, type);
+ ret = lwmi_cd_alloc(priv);
if (ret)
return ret;
@@ -838,10 +831,11 @@ static int lwmi_cd_probe(struct wmi_device *wdev, const void *context)
if (!priv)
return -ENOMEM;
+ priv->info = info;
priv->wdev = wdev;
dev_set_drvdata(&wdev->dev, priv);
- ret = lwmi_cd_setup(priv, info->type);
+ ret = lwmi_cd_setup(priv);
if (ret)
goto out;
@@ -907,7 +901,7 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
lwmi_cd_debugfs_remove(priv);
- switch (priv->list->type) {
+ switch (priv->info->type) {
case LENOVO_CAPABILITY_DATA_00:
lwmi_cd_sub_master_del(priv);
fallthrough;
--
2.55.0