From: "Heijligen, Thomas" thomas.heijligen@secunet.com
[ Upstream commit 309e65d151ab9be1e7b01d822880cd8c4e611dff ]
Commit 9e36775c22c7 ("mfd: kempld: Remove custom DMI matching code") removes the ability to load the driver if no matching system DMI data is found. Before this commit the driver could be loaded using alternative methods such as ACPI or `force_device_id` in the absence of a matching system DMI entry.
Restore this ability while keeping the refactored `platform_device_info` table.
Signed-off-by: Thomas Heijligen thomas.heijligen@secunet.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/7d2c7e92253d851194a781720051536cca2722b8.camel@sec... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
Explanation and evidence - Fixes a regression introduced by 9e36775c22c7: That commit removed the driver’s custom DMI logic, which had the unintended side-effect of preventing the driver from loading at all when there was no DMI match — even if the device could be enumerated via ACPI or by using the `force_device_id` module parameter. The new change restores the earlier init() behavior to re-enable those paths, while retaining the refactored platform_device_info usage.
What changed in init() - Adds explicit handling for `force_device_id` which lets users force- load on systems without a DMI match: - New logic iterates the static table and, if `force_device_id` matches any `ident`, creates the platform device regardless of system DMI content; otherwise returns `-ENODEV` (forced but not recognized). See `drivers/mfd/kempld-core.c:788-795`. - Allows driver registration even when no system DMI match exists: - If `force_device_id` is not set, it iterates DMI matches and attempts to create the platform device; if there are no DMI matches, it simply proceeds to `platform_driver_register(&kempld_driver)` so ACPI can enumerate and bind the device. See `drivers/mfd/kempld- core.c:796-800`. - The comment in the new code explicitly documents the restored behavior for three init paths: `force_device_id`, DMI presence, and ACPI. See `drivers/mfd/kempld-core.c:781-787`.
Why this is needed and safe - ACPI path is already supported in the driver: - The driver has an ACPI match table with IDs `KEM0000` and `KEM0001`, mapping to `kempld_platform_data_generic`. See `drivers/mfd/kempld- core.c:476-484`. - The probe path explicitly handles the “no DMI-created pdev” case by detecting `IS_ERR_OR_NULL(kempld_pdev)` and pulling platform data from ACPI via `device_get_match_data()`, then attaching it with `platform_device_add_data()`. See `drivers/mfd/kempld- core.c:414-426`. - The change is minimal and contained: - Only `kempld_init()` changes; no hardware access paths or core MFD logic are modified. It simply restores prior init semantics while keeping the newer `platform_device_info` setup. - No broad side effects: - The module still uses `MODULE_DEVICE_TABLE(dmi, ...)` and `MODULE_DEVICE_TABLE(acpi, ...)`, preserving automatic module loading under both DMI and ACPI. - Cleanup is safe: `platform_device_unregister(kempld_pdev)` remains unconditional in exit, and it is safe even if `kempld_pdev` is NULL or an ERR_PTR due to guards in the platform core (`platform_device_del()`/`platform_device_put()` both check `IS_ERR_OR_NULL`). See `drivers/base/platform.c:791-796`, `drivers/base/platform.c:746-765`, and `drivers/base/platform.c:520-560`.
Risk and regression assessment - Scope is limited to init-time enumeration policy; no architectural changes. - Restores previously supported user-visible behavior (loading via ACPI or `force_device_id`) that was inadvertently removed — i.e., a clear regression fix. - Typical DMI matching will still create a single platform device; in the common case only one DMI entry matches, so the else-branch loop behavior is equivalent to break-on-success in practice. - No impact on other subsystems; MFD-specific and self-contained.
Backport prerequisites - This should be backported to stable trees that already contain commit 9e36775c22c7 (the refactoring that removed custom DMI matching). Older trees that still have the original pre-9e36775 behavior do not need this change.
Conclusion - This is an appropriate, low-risk regression fix that restores ACPI and `force_device_id` load paths, with contained changes and clear correctness. It fits stable policy well.
drivers/mfd/kempld-core.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index c5bfb6440a930..77980c7fc31f9 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c @@ -779,22 +779,26 @@ MODULE_DEVICE_TABLE(dmi, kempld_dmi_table); static int __init kempld_init(void) { const struct dmi_system_id *id; - int ret = -ENODEV;
- for (id = dmi_first_match(kempld_dmi_table); id; id = dmi_first_match(id + 1)) { - /* Check, if user asked for the exact device ID match */ - if (force_device_id[0] && !strstr(id->ident, force_device_id)) - continue; - - ret = kempld_create_platform_device(&kempld_platform_data_generic); - if (ret) - continue; - - break; + /* + * This custom DMI iteration allows the driver to be initialized in three ways: + * - When a forced_device_id string matches any ident in the kempld_dmi_table, + * regardless of whether the DMI device is present in the system dmi table. + * - When a matching entry is present in the DMI system tabe. + * - Through alternative mechanisms like ACPI. + */ + if (force_device_id[0]) { + for (id = kempld_dmi_table; id->matches[0].slot != DMI_NONE; id++) + if (strstr(id->ident, force_device_id)) + if (!kempld_create_platform_device(&kempld_platform_data_generic)) + break; + if (id->matches[0].slot == DMI_NONE) + return -ENODEV; + } else { + for (id = dmi_first_match(kempld_dmi_table); id; id = dmi_first_match(id+1)) + if (kempld_create_platform_device(&kempld_platform_data_generic)) + break; } - if (ret) - return ret; - return platform_driver_register(&kempld_driver); }