This is a note to let you know that I've just added the patch titled power: supply: bq27xxx: Ensure power_supply_changed() is called on current sign changes to the 6.1-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: power-supply-bq27xxx-ensure-power_supply_changed-is-called-on-current-sign-changes.patch and it can be found in the queue-6.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 939a116142012926e25de0ea6b7e2f8d86a5f1b6 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@xxxxxxxxxx> Date: Sat, 15 Apr 2023 20:23:37 +0200 Subject: power: supply: bq27xxx: Ensure power_supply_changed() is called on current sign changes From: Hans de Goede <hdegoede@xxxxxxxxxx> commit 939a116142012926e25de0ea6b7e2f8d86a5f1b6 upstream. On gauges where the current register is signed, there is no charging flag in the flags register. So only checking flags will not result in power_supply_changed() getting called when e.g. a charger is plugged in and the current sign changes from negative (discharging) to positive (charging). This causes userspace's notion of the status to lag until userspace does a poll. And when a power_supply_leds.c LED trigger is used to indicate charging status with a LED, this LED will lag until the capacity percentage changes, which may take many minutes (because the LED trigger only is updated on power_supply_changed() calls). Fix this by calling bq27xxx_battery_current_and_status() on gauges with a signed current register and checking if the status has changed. Fixes: 297a533b3e62 ("bq27x00: Cache battery registers") Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> Signed-off-by: Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/power/supply/bq27xxx_battery.c | 13 ++++++++++++- include/linux/power/bq27xxx_battery.h | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -1836,6 +1836,7 @@ static int bq27xxx_battery_current_and_s static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di) { + union power_supply_propval status = di->last_status; struct bq27xxx_reg_cache cache = {0, }; bool has_singe_flag = di->opts & BQ27XXX_O_ZERO; @@ -1860,14 +1861,24 @@ static void bq27xxx_battery_update_unloc if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR) cache.cycle_count = bq27xxx_battery_read_cyct(di); + /* + * On gauges with signed current reporting the current must be + * checked to detect charging <-> discharging status changes. + */ + if (!(di->opts & BQ27XXX_O_ZERO)) + bq27xxx_battery_current_and_status(di, NULL, &status, &cache); + /* We only have to read charge design full once */ if (di->charge_design_full <= 0) di->charge_design_full = bq27xxx_battery_read_dcap(di); } if ((di->cache.capacity != cache.capacity) || - (di->cache.flags != cache.flags)) + (di->cache.flags != cache.flags) || + (di->last_status.intval != status.intval)) { + di->last_status.intval = status.intval; power_supply_changed(di->bat); + } if (memcmp(&di->cache, &cache, sizeof(cache)) != 0) di->cache = cache; --- a/include/linux/power/bq27xxx_battery.h +++ b/include/linux/power/bq27xxx_battery.h @@ -2,6 +2,8 @@ #ifndef __LINUX_BQ27X00_BATTERY_H__ #define __LINUX_BQ27X00_BATTERY_H__ +#include <linux/power_supply.h> + enum bq27xxx_chip { BQ27000 = 1, /* bq27000, bq27200 */ BQ27010, /* bq27010, bq27210 */ @@ -70,6 +72,7 @@ struct bq27xxx_device_info { int charge_design_full; bool removed; unsigned long last_update; + union power_supply_propval last_status; struct delayed_work work; struct power_supply *bat; struct list_head list; Patches currently in stable-queue which might be from hdegoede@xxxxxxxxxx are queue-6.1/power-supply-leds-fix-blink-to-led-on-transition.patch queue-6.1/platform-x86-hp-wmi-fix-cast-to-smaller-integer-type-warning.patch queue-6.1/power-supply-bq25890-call-power_supply_changed-after-updating-input-current-or-voltage.patch queue-6.1/power-supply-bq27xxx-ensure-power_supply_changed-is-called-on-current-sign-changes.patch queue-6.1/power-supply-bq27xxx-move-bq27xxx_battery_update-down.patch queue-6.1/platform-x86-intel-ifs-annotate-work-queue-on-stack-so-object-debug-does-not-complain.patch queue-6.1/power-supply-bq25890-fix-external_power_changed-race.patch queue-6.1/power-supply-bq27xxx-fix-i2c-irq-race-on-remove.patch queue-6.1/power-supply-bq27xxx-fix-bq27xxx_battery_update-race-condition.patch queue-6.1/power-supply-bq27xxx-add-cache-parameter-to-bq27xxx_battery_current_and_status.patch queue-6.1/power-supply-bq27xxx-fix-poll_interval-handling-and-races-on-remove.patch queue-6.1/power-supply-bq24190-call-power_supply_changed-after-updating-input-current.patch queue-6.1/platform-x86-isst-remove-8-socket-limit.patch queue-6.1/power-supply-axp288_fuel_gauge-fix-external_power_changed-race.patch queue-6.1/power-supply-bq27xxx-after-charger-plug-in-out-wait-0.5s-for-things-to-stabilize.patch