[PATCH RESEND] mfd: adp5520: Release the subdevices when the client is removed
From: Wentao Liang
Date: Tue Nov 03 2026 - 04:59:45 EST
adp5520_probe() registers up to four platform devices (keys, GPIO, LED
and backlight) as children of the I2C client, but the driver no longer
has a remove callback. The callback was dropped when the driver was
made explicitly non-modular, on the assumption that a built-in driver is
never removed. That assumption does not hold when the I2C adapter the
client sits on goes away: the driver core still calls the driver's
remove callback, and without one the child platform devices are never
unregistered. They stay registered, keep a reference on the I2C client
device and leak the memory they were allocated from.
adp5520_remove_subdevs() already exists and is used by the probe error
path, but it is not reachable on the removal path. Add a remove
callback that unregisters the subdevices and drops the interrupt, in the
same order as the probe error path.
Fixes: 6b09274bacc7 ("mfd: adp5520: Make it explicitly non-modular")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/mfd/adp5520.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
index bd6f4965ebc8..6b53b00efe52 100644
--- a/drivers/mfd/adp5520.c
+++ b/drivers/mfd/adp5520.c
@@ -305,6 +305,16 @@ static int adp5520_probe(struct i2c_client *client)
return ret;
}
+static void adp5520_remove(struct i2c_client *client)
+{
+ struct adp5520_chip *chip = i2c_get_clientdata(client);
+
+ adp5520_remove_subdevs(chip);
+
+ if (chip->irq)
+ free_irq(chip->irq, chip);
+}
+
static int adp5520_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -341,6 +351,7 @@ static struct i2c_driver adp5520_driver = {
.suppress_bind_attrs = true,
},
.probe = adp5520_probe,
+ .remove = adp5520_remove,
.id_table = adp5520_id,
};
builtin_i2c_driver(adp5520_driver);
--
2.34.1