From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 6c7115cdf6440e1e2f15e21efe92e2b757940627 ]
Device can be unbound, so driver must also release memory for the wakeup source.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-4-318e14bdba0a... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
Perfect! Now I have all the information I need to make a comprehensive analysis.
**YES**
This commit should be backported to stable kernel trees.
**Extensive Analysis:**
**1. Nature of the Bug:** The commit fixes a wakeup source memory leak that occurs when the max77541 MFD device is unbound. The current code in `max77541_pmic_setup()` at line 155 calls `device_init_wakeup(dev, true)` to enable wakeup capability, but there's no corresponding cleanup when the device is removed.
**2. Code Change Analysis:** The fix replaces: ```c ret = device_init_wakeup(dev, true); ``` with: ```c ret = devm_device_init_wakeup(dev); ```
This is a classic resource management improvement. The `devm_device_init_wakeup()` function (as seen in `/home/sasha/linux/include/linux/pm_wakeup.h`) automatically registers a cleanup action via `devm_add_action_or_reset()` that calls `device_disable_wakeup()` when the device is removed, preventing the memory leak.
**3. Driver Context:** - The max77541 driver was introduced in April 2023 (commit e0cbc202388a) - It's an I2C-based MFD driver for MAX77541/MAX77540 PMICs - The driver has **no remove function** (line 213-214 shows only `.probe` in the driver structure), making this cleanup particularly important since only devm-managed resources will be cleaned up automatically - The driver uses devm-managed functions extensively (devm_kzalloc, devm_regmap_init_i2c, devm_mfd_add_devices), showing this change fits the existing pattern
**4. Comparison with Similar Commits:** This commit follows the exact same pattern as the "YES" backport examples: - **Similar Commit #1 (gpio-mpc8xxx.c)**: Same fix pattern, same wakeup leak issue, marked YES for backport with explicit `Cc: stable@vger.kernel.org` - **Similar Commit #2 (gpio-zynq.c)**: Same fix pattern, same wakeup leak issue, marked YES for backport with explicit `Cc: stable@vger.kernel.org`
The change is identical in nature to these GPIO drivers that were deemed suitable for stable backporting.
**5. Stable Tree Criteria Assessment:** - ✅ **Fixes important bug**: Memory leaks affect system stability over time - ✅ **Small and contained**: Single line change, minimal risk - ✅ **No architectural changes**: Uses existing devm infrastructure - ✅ **No new features**: Pure bugfix - ✅ **Minimal regression risk**: devm_device_init_wakeup() is well- established and widely used - ✅ **Clear benefit**: Prevents resource leaks in production systems
**6. Impact and Risk Assessment:** - **Impact**: Prevents memory leaks when max77541 devices are unbound (e.g., module unload, device removal, system suspend/resume cycles) - **Risk**: Extremely low - the devm framework is mature and this pattern is used extensively across the kernel - **Regression potential**: Minimal - the functionality remains identical, just with proper cleanup
**7. Subsystem Considerations:** The MFD subsystem handles critical power management ICs. Memory leaks in power management drivers can lead to system instability, especially in embedded systems where the max77541 PMIC would typically be used.
This is a textbook example of a stable-worthy commit: it fixes a real resource management bug with a minimal, well-tested change that follows established kernel patterns.
drivers/mfd/max77541.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/max77541.c b/drivers/mfd/max77541.c index d77c31c86e435..f91b4f5373ce9 100644 --- a/drivers/mfd/max77541.c +++ b/drivers/mfd/max77541.c @@ -152,7 +152,7 @@ static int max77541_pmic_setup(struct device *dev) if (ret) return dev_err_probe(dev, ret, "Failed to initialize IRQ\n");
- ret = device_init_wakeup(dev, true); + ret = devm_device_init_wakeup(dev); if (ret) return dev_err_probe(dev, ret, "Unable to init wakeup\n");