All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] power: supply: twl4030_charger: cancel work on remove
@ 2026-07-28 12:33 Hongyan Xu
  0 siblings, 0 replies; only message in thread
From: Hongyan Xu @ 2026-07-28 12:33 UTC (permalink / raw)
  To: sre; +Cc: Hongyan Xu, linux-pm, linux-kernel, jianhao.xu

The USB notifier schedules bci->work and the charger current path can
requeue bci->current_worker. Both work items use bci, but bci is
devm-allocated and remove did not stop them before devres cleanup.

Get the USB PHY without a managed notifier, register the notifier
explicitly, then unregister it and mask external event sources before
cancelling both work items in remove.

This issue was found by a static analysis tool.

Signed-off-by: Hongyan Xu <getshell@seu.edu.cn>
---
 drivers/power/supply/twl4030_charger.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/power/supply/twl4030_charger.c b/drivers/power/supply/twl4030_charger.c
index 9dcb5457b..0142259ec 100644
--- a/drivers/power/supply/twl4030_charger.c
+++ b/drivers/power/supply/twl4030_charger.c
@@ -116,6 +116,7 @@ struct twl4030_bci {
 	struct usb_phy		*transceiver;
 	struct notifier_block	usb_nb;
 	struct work_struct	work;
+	bool			usb_nb_registered;
 	int			irq_chg;
 	int			irq_bci;
 	int			usb_enabled;
@@ -1024,7 +1025,7 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		if (phynode) {
 			bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;
 			bci->transceiver = devm_usb_get_phy_by_node(
-				bci->dev, phynode, &bci->usb_nb);
+				bci->dev, phynode, NULL);
 			of_node_put(phynode);
 			if (IS_ERR(bci->transceiver)) {
 				ret = PTR_ERR(bci->transceiver);
@@ -1033,6 +1034,15 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 				dev_warn(&pdev->dev, "could not request transceiver (%d)",
 					ret);
 				bci->transceiver = NULL;
+			} else {
+				ret = usb_register_notifier(bci->transceiver,
+							    &bci->usb_nb);
+				if (ret)
+					dev_warn(&pdev->dev,
+						 "could not register USB notifier (%d)\n",
+						 ret);
+				else
+					bci->usb_nb_registered = true;
 			}
 		}
 	}
@@ -1112,17 +1122,25 @@ static void twl4030_bci_remove(struct platform_device *pdev)
 {
 	struct twl4030_bci *bci = platform_get_drvdata(pdev);
 
-	twl4030_charger_enable_ac(bci, false);
-	twl4030_charger_enable_usb(bci, false);
-	twl4030_charger_enable_backup(0, 0);
+	if (bci->usb_nb_registered)
+		usb_unregister_notifier(bci->transceiver, &bci->usb_nb);
 
 	device_remove_file(&bci->usb->dev, &dev_attr_mode);
 	device_remove_file(&bci->ac->dev, &dev_attr_mode);
+
 	/* mask interrupts */
 	twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
 			 TWL4030_INTERRUPTS_BCIIMR1A);
 	twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
 			 TWL4030_INTERRUPTS_BCIIMR2A);
+
+	cancel_work_sync(&bci->work);
+	bci->usb_cur_target = 0;
+	cancel_delayed_work_sync(&bci->current_worker);
+
+	twl4030_charger_enable_ac(bci, false);
+	twl4030_charger_enable_usb(bci, false);
+	twl4030_charger_enable_backup(0, 0);
 }
 
 static const struct of_device_id twl_bci_of_match[] __maybe_unused = {
-- 
2.50.1.windows.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-28 12:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-28 12:33 [PATCH] power: supply: twl4030_charger: cancel work on remove Hongyan Xu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.