| From 5b74d1d16e2f5753fcbdecd6771b2d8370dda414 Mon Sep 17 00:00:00 2001 |
| From: Hans de Goede <hdegoede@redhat.com> |
| Date: Tue, 10 Dec 2019 10:57:51 +0100 |
| Subject: ACPI / battery: Use design-cap for capacity calculations if full-cap is not available |
| |
| From: Hans de Goede <hdegoede@redhat.com> |
| |
| commit 5b74d1d16e2f5753fcbdecd6771b2d8370dda414 upstream. |
| |
| The ThunderSoft TS178 tablet's _BIX implementation reports design_capacity |
| but not full_charge_capacity. |
| |
| Before this commit this would cause us to return -ENODEV for the capacity |
| attribute, which userspace does not like. Specifically upower does this: |
| |
| if (sysfs_file_exists (native_path, "capacity")) { |
| percentage = sysfs_get_double (native_path, "capacity"); |
| |
| Where the sysfs_get_double() helper returns 0 when we return -ENODEV, |
| so the battery always reads 0% if we return -ENODEV. |
| |
| This commit fixes this by using the design-capacity instead of the |
| full-charge-capacity when the full-charge-capacity is not available. |
| |
| Fixes: b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity") |
| Cc: 4.19+ <stable@vger.kernel.org> # 4.19+ |
| Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/acpi/battery.c | 11 ++++++++--- |
| 1 file changed, 8 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/acpi/battery.c |
| +++ b/drivers/acpi/battery.c |
| @@ -230,7 +230,7 @@ static int acpi_battery_get_property(str |
| enum power_supply_property psp, |
| union power_supply_propval *val) |
| { |
| - int ret = 0; |
| + int full_capacity = ACPI_BATTERY_VALUE_UNKNOWN, ret = 0; |
| struct acpi_battery *battery = to_acpi_battery(psy); |
| |
| if (acpi_battery_present(battery)) { |
| @@ -299,12 +299,17 @@ static int acpi_battery_get_property(str |
| val->intval = battery->capacity_now * 1000; |
| break; |
| case POWER_SUPPLY_PROP_CAPACITY: |
| + if (ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) |
| + full_capacity = battery->full_charge_capacity; |
| + else if (ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) |
| + full_capacity = battery->design_capacity; |
| + |
| if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || |
| - !ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) |
| + full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
| ret = -ENODEV; |
| else |
| val->intval = battery->capacity_now * 100/ |
| - battery->full_charge_capacity; |
| + full_capacity; |
| break; |
| case POWER_SUPPLY_PROP_CAPACITY_LEVEL: |
| if (battery->state & ACPI_BATTERY_STATE_CRITICAL) |