From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 9fc5986fbcd7e1e63afb04be94cd4e8a536a4b04 ]
Device can be unbound, so driver must also release memory for the wakeup source.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20250406204051.63446-1-krzysztof.kozlowski@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org ---
Excellent! Now I have a complete understanding of the issue. Based on my analysis of the commit and the code:
**YES**
This commit should be backported to stable kernel trees.
## Analysis:
### **Code Change Analysis:** The commit changes the `max_tcpci_probe()` function in `drivers/usb/typec/tcpm/tcpci_maxim_core.c:539` from: ```c device_init_wakeup(chip->dev, true); ``` to: ```c ret = devm_device_init_wakeup(chip->dev); if (ret) return dev_err_probe(chip->dev, ret, "Failed to init wakeup\n"); ```
### **Resource Leak Issue:** 1. **Memory Allocation:** When `device_init_wakeup(dev, true)` is called, it internally calls `device_wakeup_enable()` which creates and registers a `wakeup_source` object via `wakeup_source_register()`. This allocates memory for the wakeup source structure and adds it to the global wakeup sources list.
2. **Missing Cleanup:** The original code has no cleanup mechanism. When the device is unbound (driver removal), the wakeup source remains allocated and registered, causing a memory leak.
3. **Fix:** `devm_device_init_wakeup()` uses the device resource management system. It calls `devm_add_action_or_reset(dev, device_disable_wakeup, dev)`, which ensures that `device_disable_wakeup()` (which calls `device_init_wakeup(dev, false)`) is automatically called when the device is removed, properly cleaning up the wakeup source.
### **Backport Suitability:** This commit fits all the criteria for stable backporting:
1. **✅ Important Bug Fix:** Fixes a memory leak that affects users over time 2. **✅ Small and Contained:** Only 4 lines changed, very focused fix 3. **✅ No Side Effects:** Uses standard kernel resource management patterns 4. **✅ No Architectural Changes:** Just switches to managed resource API 5. **✅ Critical Subsystem:** USB Type-C is widely used and important 6. **✅ Minimal Risk:** `devm_device_init_wakeup()` is a well-established API 7. **✅ Follows Stable Rules:** Classic resource leak fix with minimal regression risk
### **Historical Precedent:** This fix is identical in nature to Similar Commit #1 (gpio: mpc8xxx) which was marked as "Backport Status: YES" and even has the same `Cc: stable@vger.kernel.org` tag in its commit message. Both commits fix the exact same type of wakeup source leak using the identical solution.
The commit addresses a real resource management issue that would accumulate over time in systems where Type-C devices are frequently bound/unbound, and the fix is both safe and standard.
drivers/usb/typec/tcpm/tcpci_maxim_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/typec/tcpm/tcpci_maxim_core.c b/drivers/usb/typec/tcpm/tcpci_maxim_core.c index fd1b805933676..29a4aa89d1a14 100644 --- a/drivers/usb/typec/tcpm/tcpci_maxim_core.c +++ b/drivers/usb/typec/tcpm/tcpci_maxim_core.c @@ -536,7 +536,10 @@ static int max_tcpci_probe(struct i2c_client *client) return dev_err_probe(&client->dev, ret, "IRQ initialization failed\n");
- device_init_wakeup(chip->dev, true); + ret = devm_device_init_wakeup(chip->dev); + if (ret) + return dev_err_probe(chip->dev, ret, "Failed to init wakeup\n"); + return 0; }