[PATCH 3/4] ACPI / battery: Add handling for devices which wrongly report discharging state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On quite a few devices the battery code in the ACPI tables is buggy and
first checks the charging status bits of the charger-IC, and if those
report not charging it will report discharging, without looking at the
presence of AC power or at the battery dis(charge) current from the
fuel-gauge.

This causes the wrong status to be reported for the battery in the
following quite common scenario:

1) Plug in charger while battery is say half full, battery starts
charging, charging state bits indicate: pre-charge or fast-charge,
ACPI reported battery status is ok

2) When fully charged charging state bits indicate: end-of-charge,
ACPI reported battery status is ok

3) unplug the charger, wait 1 minute, replug. Now the battery voltage is
still above the start-charging threshold, so the charger will not start
charging to avoid wrecking the battery by repeatedly recharging the last 1%
capacity. The charger IC charging state bits now are all 0 (not-charging)
and the broken ACPI code wrongly translate this to "discharging" and ends
up setting the ACPI_BATTERY_STATE_DISCHARGING bit in its state field.

Reporting this "not charging" state as discharging is confusing for users,
making the user think his adapter/power-brick is broken or not properly
plugged in.

This commit adds a helper for handling the ACPI_BATTERY_STATE_DISCHARGING
state. This helper checks if we're an AC and the current going out of the
battery is 0 and in that case reports a status of full to userspace rather
then discharging.

This replaces commit c68f0676ef7d ("ACPI / battery: Add quirk for Asus
GL502VSK and UX305LA"), a previous fix for this which was reverted.

Cc: Kai-Heng Feng <kai.heng.feng@xxxxxxxxxxxxx>
Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
---
 drivers/acpi/battery.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 1fc0feceafaf..86c55f3b59f4 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -200,6 +200,27 @@ static int acpi_battery_is_charged(struct acpi_battery *battery)
 	return 0;
 }
 
+static int acpi_battery_handle_discharging(struct acpi_battery *battery)
+{
+	/*
+	 * Some devices wrongly report discharging if the battery's charge level
+	 * was above the device's start charging threshold atm the AC adapter
+	 * was plugged in and the device thus did not start a new charge cycle.
+	 */
+	if (power_supply_is_system_supplied() && battery->rate_now == 0) {
+		/*
+		 * 20180409: Ideally we would use STATUS_NOT_CHARGING here, but
+		 * that trips a bug in userspace, so for now we use FULL, see:
+		 * https://bugs.freedesktop.org/attachment.cgi?id=138070
+		 * Note that the fix for that bug translates not-charging to
+		 * full, so it does not matter much anyways.
+		 */
+		return POWER_SUPPLY_STATUS_FULL;
+	}
+
+	return POWER_SUPPLY_STATUS_DISCHARGING;
+}
+
 static int acpi_battery_get_property(struct power_supply *psy,
 				     enum power_supply_property psp,
 				     union power_supply_propval *val)
@@ -215,7 +236,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
 		if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
-			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+			val->intval = acpi_battery_handle_discharging(battery);
 		else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
 		else if (acpi_battery_is_charged(battery))
-- 
2.17.0

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux