[PATCH 13/28] mfd: twl-core: Clear pm_power_off callback in twl_remove()
From: Lee Jones
Date: Wed Oct 21 2026 - 08:26:19 EST
When a TWL6030-class device is configured as the system power
controller, twl_probe() registers twl6030_power_off() as the global
pm_power_off callback. However, twl_remove() does not clear
pm_power_off when tearing down the device on late probe failure or
driver unbind, leaving a dangling callback that dereferences the freed
twl_priv context during system shutdown.
Reset pm_power_off to NULL in twl_remove() when it points to
twl6030_power_off().
Fixes: ca9414a1d087 ("mfd: twl-core: Add power off implementation for twl603x")
Closes: https://sashiko.dev/#/bug/linux-f5847f26-c868-416a-b926-3fc3da57802d
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Lee Jones <lee@xxxxxxxxxx>
---
drivers/mfd/twl-core.c | 29 ++++++++++++++++-------------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index c024a28b057e..64b45fe79159 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -672,10 +672,26 @@ static void clocks_init(struct device *dev)
/*----------------------------------------------------------------------*/
+static void twl6030_power_off(void)
+{
+ int err;
+ u8 val;
+
+ err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val, TWL6030_PHOENIX_DEV_ON);
+ if (err)
+ return;
+
+ val |= TWL6030_APP_DEVOFF | TWL6030_CON_DEVOFF | TWL6030_MOD_DEVOFF;
+ twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val, TWL6030_PHOENIX_DEV_ON);
+}
+
static void twl_remove(struct i2c_client *client)
{
unsigned i, num_slaves;
+ if (pm_power_off == twl6030_power_off)
+ pm_power_off = NULL;
+
if (twl_class_is_4030())
twl4030_exit_irq();
else
@@ -692,19 +708,6 @@ static void twl_remove(struct i2c_client *client)
twl_priv->ready = false;
}
-static void twl6030_power_off(void)
-{
- int err;
- u8 val;
-
- err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val, TWL6030_PHOENIX_DEV_ON);
- if (err)
- return;
-
- val |= TWL6030_APP_DEVOFF | TWL6030_CON_DEVOFF | TWL6030_MOD_DEVOFF;
- twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val, TWL6030_PHOENIX_DEV_ON);
-}
-
static struct of_dev_auxdata twl_auxdata_lookup[] = {
OF_DEV_AUXDATA("ti,twl4030-gpio", 0, "twl4030-gpio", NULL),
--
2.56.0.218.g1ec904b173-goog