From 6c8098e04ee4d233399e40e7311715844910f8f8 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 8 Oct 2026 11:14:57 +0200 Subject: [PATCH] power: supply: qcom_battmgr: report full batteries The SC8280XP battery-status response has no explicit full state. When a battery reaches its full capacity on external power, neither the charging nor discharging bit is set. The driver consequently reports "Not charging", which can make userspace show the system as battery powered. Use the response's power-online bit and the reported capacity to identify a battery that is full while externally powered. Preserve "Not charging" for a battery whose charging is inhibited below its full capacity. Fixes: 29e8142b5623 ("power: supply: Introduce Qualcomm PMIC GLINK power supply") Assisted-by: LLM Signed-off-by: Bjorn Andersson Reviewed-by: Konrad Dybcio Link: https://patch.msgid.link/20261008-battmgr-full-v1-1-4f5485a9c421@oss.qualcomm.com [put variable definition in Reverse-Christmas-tree order] Signed-off-by: Sebastian Reichel --- drivers/power/supply/qcom_battmgr.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/power/supply/qcom_battmgr.c b/drivers/power/supply/qcom_battmgr.c index 99ae0920f726..636d6f6acecc 100644 --- a/drivers/power/supply/qcom_battmgr.c +++ b/drivers/power/supply/qcom_battmgr.c @@ -1277,6 +1277,7 @@ static void qcom_battmgr_sc8280xp_callback(struct qcom_battmgr *battmgr, size_t len) { unsigned int opcode = le32_to_cpu(resp->hdr.opcode); + unsigned int power_state; unsigned int source; unsigned int state; size_t payload_len = len - sizeof(struct pmic_glink_hdr); @@ -1327,19 +1328,24 @@ static void qcom_battmgr_sc8280xp_callback(struct qcom_battmgr *battmgr, return; } - state = le32_to_cpu(resp->status.battery_state); - if (state & BIT(0)) - battmgr->status.status = POWER_SUPPLY_STATUS_DISCHARGING; - else if (state & BIT(1)) - battmgr->status.status = POWER_SUPPLY_STATUS_CHARGING; - else - battmgr->status.status = POWER_SUPPLY_STATUS_NOT_CHARGING; - battmgr->status.capacity = le32_to_cpu(resp->status.capacity) * 1000; battmgr->status.power_now = le32_to_cpu(resp->status.rate) * 1000; battmgr->status.voltage_now = le32_to_cpu(resp->status.battery_voltage) * 1000; battmgr->status.temperature = qcom_battmgr_sc8280xp_convert_temp(le32_to_cpu(resp->status.temperature)); + state = le32_to_cpu(resp->status.battery_state); + power_state = le32_to_cpu(resp->status.power_state); + if (state & BIT(0)) + battmgr->status.status = POWER_SUPPLY_STATUS_DISCHARGING; + else if (state & BIT(1)) + battmgr->status.status = POWER_SUPPLY_STATUS_CHARGING; + else if ((power_state & BIT(0)) && + battmgr->info.last_full_capacity && + battmgr->status.capacity >= battmgr->info.last_full_capacity) + battmgr->status.status = POWER_SUPPLY_STATUS_FULL; + else + battmgr->status.status = POWER_SUPPLY_STATUS_NOT_CHARGING; + source = le32_to_cpu(resp->status.charging_source); qcom_battmgr_sc8280xp_set_online(battmgr->ac_psy, &battmgr->ac.online, source == BATTMGR_CHARGING_SOURCE_AC);