diff mbox series

[1/8] power: supply: Use power_supply_external_power_changed() in __power_supply_changed_work()

Message ID 20241215172133.178460-2-hdegoede@redhat.com (mailing list archive)
State Handled Elsewhere, archived
Headers show
Series power: supply: Add adc-battery-helper lib and Intel Dollar Cove TI CC battery driver | expand

Commit Message

Hans de Goede Dec. 15, 2024, 5:21 p.m. UTC
The power-supply core is designed so that power-supply driver callbacks
such as get_property() and external_power_changed() will not be called
until the power-supply's parent driver's probe() function has completed.

There is a race where power_supply_changed() can be called for a supplier
of a power-supply which is being probed after the device_add() in
__power_supply_register() but before the parent driver's probe() function
has completed. Hitting this race breaks the power-supply core's design
to not call power-supply driver callbacks before probe() completion.

This problem is caused by __power_supply_changed_work() calling
the external_power_changed() directly rather then going through
the power_supply_external_power_changed() helper which correcly checks
psy->use_cnt .

Switch to using power_supply_external_power_changed() to fix this race.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/power/supply/power_supply_core.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index 76ebaef403ed..54ee4c83b32f 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -70,10 +70,8 @@  static int __power_supply_changed_work(struct power_supply *pst, void *data)
 {
 	struct power_supply *psy = data;
 
-	if (__power_supply_is_supplied_by(psy, pst)) {
-		if (pst->desc->external_power_changed)
-			pst->desc->external_power_changed(pst);
-	}
+	if (__power_supply_is_supplied_by(psy, pst))
+		power_supply_external_power_changed(pst);
 
 	return 0;
 }