]> www.infradead.org Git - users/willy/xarray.git/commitdiff
power: supply: Use power_supply_external_power_changed() in __power_supply_changed_work()
authorHans de Goede <hdegoede@redhat.com>
Sun, 15 Dec 2024 17:21:24 +0000 (18:21 +0100)
committerSebastian Reichel <sebastian.reichel@collabora.com>
Thu, 19 Dec 2024 23:36:05 +0000 (00:36 +0100)
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>
Link: https://lore.kernel.org/r/20241215172133.178460-2-hdegoede@redhat.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
drivers/power/supply/power_supply_core.c

index eeeed1216e22595de75d1d2a482de4a5e6901773..d0bb52a7a0367a8e07787be211691cad14a41a54 100644 (file)
@@ -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;
 }