Re: [PATCH 4/9] platform/x86: lenovo-wmi-{capdata,other}: Only allocate capdata list when necessary
From: Ilpo Järvinen
Date: Mon Oct 05 2026 - 12:29:29 EST
On Mon, 14 Sep 2026, Rong Zhang wrote:
> When no capability data is available, there is no need to allocate
> capability data list as it's basically unused except for the
> priv->list->count == 0 placeholder.
>
> Therefore, only allocate priv->list when necessary, otherwise its
> absence implies the absence of capability data. In this manner,
> lenovo-wmi-other can skip registering unavailable functionalities
> accordingly. Meanwhile, skip creating the debugfs directory as it
> provides nothing when there is no capability data.
>
> Signed-off-by: Rong Zhang <i@xxxxxxxx>
> ---
> drivers/platform/x86/lenovo/wmi-capdata.c | 43 ++++++++++++++++++++++---------
> drivers/platform/x86/lenovo/wmi-other.c | 11 +++++---
> 2 files changed, 38 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
> index 0123ec8f7b53..793b5103d533 100644
> --- a/drivers/platform/x86/lenovo/wmi-capdata.c
> +++ b/drivers/platform/x86/lenovo/wmi-capdata.c
> @@ -313,8 +313,8 @@ static const struct component_ops lwmi_cd_component_ops = {
> * @dev: The sub-master capdata basic device.
> *
> * Call component_bind_all to bind the sub-component device to the sub-master
> - * device. On success, collect the pointer to the sub-component list and try
> - * to call the master callback.
> + * device. On success, collect the pointer (or ERR_PTR(-ENODEV) if it's stubbed)
> + * to the sub-component list and try to call the master callback.
> *
> * Return: 0 on success, or an error code.
> */
> @@ -328,7 +328,7 @@ static int lwmi_cd_sub_master_bind(struct device *dev)
> if (ret)
> return ret;
>
> - priv->sub_master->sub_component_list = sub_component_list;
> + priv->sub_master->sub_component_list = sub_component_list ?: ERR_PTR(-ENODEV);
> lwmi_cd_call_master_cb(priv);
>
> return 0;
> @@ -460,6 +460,9 @@ static const struct component_ops lwmi_cd_sub_component_ops = {
> { \
> u8 idx; \
> \
> + if (WARN_ON(!list)) \
> + return -EINVAL; \
> + \
> guard(mutex)(&list->list_mutex); \
> for (idx = 0; idx < list->count; idx++) { \
> if (list->_cdxx[idx].id != attribute_id) \
> @@ -571,6 +574,9 @@ DEFINE_SHOW_ATTRIBUTE(lwmi_cd_debugfs);
> */
> static void lwmi_cd_debugfs_add(struct lwmi_cd_priv *priv)
> {
> + if (!priv->list)
> + return;
> +
> priv->debugfs_dir = lwmi_debugfs_create_dir(priv->wdev);
>
> debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_fops);
> @@ -582,6 +588,7 @@ static void lwmi_cd_debugfs_add(struct lwmi_cd_priv *priv)
> */
> static void lwmi_cd_debugfs_remove(struct lwmi_cd_priv *priv)
> {
> + /* Debugfs can handle NULL dir, no need to check. */
> debugfs_remove_recursive(priv->debugfs_dir);
> priv->debugfs_dir = NULL;
> }
> @@ -645,6 +652,9 @@ static int __lwmi_cd_cache(struct lwmi_cd_priv *priv)
> */
> static int lwmi_cd_cache(struct lwmi_cd_priv *priv)
> {
> + if (!priv->list)
> + return 0;
> +
> if (!priv->initialized)
> return __lwmi_cd_cache(priv);
>
> @@ -707,6 +717,9 @@ static int lwmi_cd_fan_list_alloc_cache(struct lwmi_cd_priv *priv)
> count = 0;
> }
>
> + if (!count)
> + return 0;
> +
> list = devm_kzalloc(&priv->wdev->dev, struct_size(list, cd_fan, count), GFP_KERNEL);
> if (!list)
> return -ENOMEM;
> @@ -742,6 +755,8 @@ static int lwmi_cd_alloc(struct lwmi_cd_priv *priv)
> int count;
>
> count = wmidev_instance_count(priv->wdev);
> + if (!count)
> + return 0;
>
> switch (priv->info->type) {
> case LENOVO_CAPABILITY_DATA_00:
> @@ -884,7 +899,9 @@ static int lwmi_cd_probe(struct wmi_device *wdev, const void *context)
> enum lwmi_cd_type sub_component_type = LENOVO_FAN_TEST_DATA;
> struct capdata00 capdata00;
>
> - ret = lwmi_cd00_get_data(priv->list, LWMI_ATTR_ID_FAN_TEST, &capdata00);
> + ret = priv->list
> + ? lwmi_cd00_get_data(priv->list, LWMI_ATTR_ID_FAN_TEST, &capdata00)
> + : -ENODATA;
It's only 89 chars if you have it one a single line so this looks pretty
unnecessary line split that doesn't even buy you that much extra space.
The code can go up to 100 chars as needed.
Alternatively, split the parameters to two lines instead.
> if (ret || !(capdata00.supported & LWMI_SUPP_VALID)) {
> dev_dbg(&wdev->dev, "capdata00 declares no fan test support\n");
> sub_component_type = CD_TYPE_NONE;
> @@ -905,14 +922,16 @@ static int lwmi_cd_probe(struct wmi_device *wdev, const void *context)
> case LENOVO_CAPABILITY_DATA_01:
> priv->acpi_nb.notifier_call = lwmi_cd01_notifier_call;
>
> - ret = register_acpi_notifier(&priv->acpi_nb);
> - if (ret)
> - goto out;
> + if (priv->list) {
> + ret = register_acpi_notifier(&priv->acpi_nb);
> + if (ret)
> + goto out;
>
> - ret = devm_add_action_or_reset(&wdev->dev, lwmi_cd01_unregister,
> - &priv->acpi_nb);
> - if (ret)
> - goto out;
> + ret = devm_add_action_or_reset(&wdev->dev, lwmi_cd01_unregister,
> + &priv->acpi_nb);
> + if (ret)
> + goto out;
> + }
>
> ret = component_add(&wdev->dev, &lwmi_cd_component_ops);
> goto out;
> @@ -930,7 +949,7 @@ static int lwmi_cd_probe(struct wmi_device *wdev, const void *context)
> lwmi_cd_debugfs_add(priv);
>
> dev_dbg(&wdev->dev, "registered %s with %u items\n",
> - info->name, priv->list->count);
> + info->name, priv->list ? priv->list->count : 0);
> }
> return ret;
> }
> diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86/lenovo/wmi-other.c
> index fbb32bf404f2..e6c8f6bcf050 100644
> --- a/drivers/platform/x86/lenovo/wmi-other.c
> +++ b/drivers/platform/x86/lenovo/wmi-other.c
> @@ -1643,16 +1643,19 @@ static int lwmi_om_master_bind(struct device *dev)
>
> priv->cd00_list = binder.cd00_list;
> priv->cd01_list = binder.cd01_list;
> - if (!priv->cd00_list || !priv->cd01_list) {
> + if (!priv->cd00_list && !priv->cd01_list) {
> component_unbind_all(dev, NULL);
>
> return -ENODEV;
> }
>
> - lwmi_om_fan_info_collect_cd00(priv);
> - lwmi_om_psy_ext_init(priv);
> + if (priv->cd00_list) {
> + lwmi_om_fan_info_collect_cd00(priv);
> + lwmi_om_psy_ext_init(priv);
> + }
>
> - lwmi_om_fw_attr_add(priv);
> + if (priv->cd01_list)
> + lwmi_om_fw_attr_add(priv);
>
> return 0;
> }
>
>
--
i.