summary refs log tree commit diff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2022-11-28 10:28:48 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-12-31 13:32:45 +0100
commit64245114c072ed3f5c2f6ff11a862e3b1b6df7fe (patch)
tree40a9ca6be9f73c8b00987733a2daec7f5a416351
parent81b0e5d5aa0c4cb08bdffec4bdb97785b5459d11 (diff)
downloadlinux-64245114c072ed3f5c2f6ff11a862e3b1b6df7fe.tar.gz
power: supply: bq25890: Ensure pump_express_work is cancelled on remove
[ Upstream commit a7aaa80098d5b7608b2dc1e883e3c3f929415243 ]

The pump_express_work which gets queued from an external_power_changed
callback might be pending / running on remove() (or on probe failure).

Add a devm action cancelling the work, to ensure that it is cancelled.

Note the devm action is added before devm_power_supply_register(), making
it run after devm unregisters the power_supply, so that the work cannot
be queued anymore (this is also why a devm action is used for this).

Fixes: 48f45b094dbb ("power: supply: bq25890: Support higher charging voltages through Pump Express+ protocol")
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/power/supply/bq25890_charger.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/power/supply/bq25890_charger.c b/drivers/power/supply/bq25890_charger.c
index f212fc7cbb6d..0e15302b8df2 100644
--- a/drivers/power/supply/bq25890_charger.c
+++ b/drivers/power/supply/bq25890_charger.c
@@ -1219,6 +1219,13 @@ static int bq25890_fw_probe(struct bq25890_device *bq)
 	return 0;
 }
 
+static void bq25890_non_devm_cleanup(void *data)
+{
+	struct bq25890_device *bq = data;
+
+	cancel_delayed_work_sync(&bq->pump_express_work);
+}
+
 static int bq25890_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
@@ -1274,6 +1281,14 @@ static int bq25890_probe(struct i2c_client *client)
 	/* OTG reporting */
 	bq->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
 
+	/*
+	 * This must be before bq25890_power_supply_init(), so that it runs
+	 * after devm unregisters the power_supply.
+	 */
+	ret = devm_add_action_or_reset(dev, bq25890_non_devm_cleanup, bq);
+	if (ret)
+		return ret;
+
 	ret = bq25890_register_regulator(bq);
 	if (ret)
 		return ret;