summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorMyeonghun Pak <mhun512@gmail.com>2026-10-04 00:37:28 -0400
committerSebastian Reichel <sebastian.reichel@collabora.com>2026-10-05 00:05:56 +0200
commit4856b49317ccd4ce96a0e8970df7d13ce8975a02 (patch)
treeb7f26ad17178795802216f6d47f23db60bd372e8 /drivers/power
parentb33596a615d163372f5e7519338d860cbfc37217 (diff)
power: supply: pf1550: drain IRQ work before unregistering supplies
The VBUS work calls power_supply_changed(), but its managed cancellation is registered before the supplies. Cleanup can therefore unregister a supply while IRQ-triggered work is still pending. Commit 838767f50747 ("power: supply: pf1550: Fix use-after-free in power_supply_changed()") moved IRQ requests after supply registration, but left work cancellation before the supplies. That change protects the direct IRQ callbacks, while this fix drains the work they queue. Register the three work items after both supplies and before the IRQs. Cleanup then frees the IRQ producers, drains the work, and unregisters the supplies. The teardown ordering issue was found by static analysis. Fixes: 4b6b6433a97d ("power: supply: pf1550: add battery charger support") Cc: stable@vger.kernel.org Assisted-by: LLM Co-developed-by: Ijae Kim <ae878000@gmail.com> Signed-off-by: Ijae Kim <ae878000@gmail.com> Signed-off-by: Myeonghun Pak <mhun512@gmail.com> Link: https://patch.msgid.link/20261004043728.1140015-1-mhun512@gmail.com Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/supply/pf1550-charger.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c
index 2ead1df60e65..e3d4e9817f91 100644
--- a/drivers/power/supply/pf1550-charger.c
+++ b/drivers/power/supply/pf1550-charger.c
@@ -566,6 +566,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, chg);
+ psy_cfg.drv_data = chg;
+
+ chg->charger = devm_power_supply_register(&pdev->dev,
+ &pf1550_charger_desc,
+ &psy_cfg);
+ if (IS_ERR(chg->charger))
+ return dev_err_probe(&pdev->dev, PTR_ERR(chg->charger),
+ "failed: power supply register\n");
+
+ chg->battery = devm_power_supply_register(&pdev->dev,
+ &pf1550_battery_desc,
+ &psy_cfg);
+ if (IS_ERR(chg->battery))
+ return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
+ "failed: power supply register\n");
+
ret = devm_delayed_work_autocancel(chg->dev, &chg->vbus_sense_work,
pf1550_chg_vbus_work);
if (ret)
@@ -584,22 +600,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
return dev_err_probe(chg->dev, ret,
"failed to add battery sense work\n");
- psy_cfg.drv_data = chg;
-
- chg->charger = devm_power_supply_register(&pdev->dev,
- &pf1550_charger_desc,
- &psy_cfg);
- if (IS_ERR(chg->charger))
- return dev_err_probe(&pdev->dev, PTR_ERR(chg->charger),
- "failed: power supply register\n");
-
- chg->battery = devm_power_supply_register(&pdev->dev,
- &pf1550_battery_desc,
- &psy_cfg);
- if (IS_ERR(chg->battery))
- return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
- "failed: power supply register\n");
-
for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
irq = platform_get_irq(pdev, i);
if (irq < 0)