Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52dbcdb2 authored by Hans de Goede's avatar Hans de Goede Committed by Greg Kroah-Hartman
Browse files

ACPI / battery: Deal with design or full capacity being reported as -1



commit cc99f0ad52467028cb1251160f23ad4bb65baf20 upstream.

Commit b41901a2 ("ACPI / battery: Do not export energy_full[_design]
on devices without full_charge_capacity") added support for some (broken)
devices which always report 0 for both design- and full_charge-capacity.

This assumes that if the capacity is not being reported it is 0. The
ThunderSoft TS178 tablet's _BIX implementation falsifies this assumption.
It reports ACPI_BATTERY_VALUE_UNKNOWN (-1) as full_charge_capacity, which
we treat as a valid value which causes several problems.

This commit fixes this by adding a new ACPI_BATTERY_CAPACITY_VALID() helper
which checks that the value is not 0 and not -1; and using this whenever we
need to test if either design_capacity or full_charge_capacity is valid.

Fixes: b41901a2 ("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: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7751179a
Loading
Loading
Loading
Loading
+12 −7
Original line number Original line Diff line number Diff line
@@ -51,6 +51,8 @@
#define PREFIX "ACPI: "
#define PREFIX "ACPI: "


#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
#define ACPI_BATTERY_CAPACITY_VALID(capacity) \
	((capacity) != 0 && (capacity) != ACPI_BATTERY_VALUE_UNKNOWN)


#define ACPI_BATTERY_DEVICE_NAME	"Battery"
#define ACPI_BATTERY_DEVICE_NAME	"Battery"


@@ -205,7 +207,8 @@ static int acpi_battery_is_charged(struct acpi_battery *battery)


static bool acpi_battery_is_degraded(struct acpi_battery *battery)
static bool acpi_battery_is_degraded(struct acpi_battery *battery)
{
{
	return battery->full_charge_capacity && battery->design_capacity &&
	return ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
		ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity) &&
		battery->full_charge_capacity < battery->design_capacity;
		battery->full_charge_capacity < battery->design_capacity;
}
}


@@ -276,14 +279,14 @@ static int acpi_battery_get_property(struct power_supply *psy,
		break;
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
		if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
		if (!ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
			ret = -ENODEV;
			ret = -ENODEV;
		else
		else
			val->intval = battery->design_capacity * 1000;
			val->intval = battery->design_capacity * 1000;
		break;
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL:
	case POWER_SUPPLY_PROP_CHARGE_FULL:
	case POWER_SUPPLY_PROP_ENERGY_FULL:
	case POWER_SUPPLY_PROP_ENERGY_FULL:
		if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
		if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
			ret = -ENODEV;
			ret = -ENODEV;
		else
		else
			val->intval = battery->full_charge_capacity * 1000;
			val->intval = battery->full_charge_capacity * 1000;
@@ -296,11 +299,12 @@ static int acpi_battery_get_property(struct power_supply *psy,
			val->intval = battery->capacity_now * 1000;
			val->intval = battery->capacity_now * 1000;
		break;
		break;
	case POWER_SUPPLY_PROP_CAPACITY:
	case POWER_SUPPLY_PROP_CAPACITY:
		if (battery->capacity_now && battery->full_charge_capacity)
		if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
		    !ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
			ret = -ENODEV;
		else
			val->intval = battery->capacity_now * 100/
			val->intval = battery->capacity_now * 100/
					battery->full_charge_capacity;
					battery->full_charge_capacity;
		else
			val->intval = 0;
		break;
		break;
	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
		if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
		if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
@@ -812,7 +816,8 @@ static int sysfs_add_battery(struct acpi_battery *battery)
		battery->bat_desc.properties = charge_battery_props;
		battery->bat_desc.properties = charge_battery_props;
		battery->bat_desc.num_properties =
		battery->bat_desc.num_properties =
			ARRAY_SIZE(charge_battery_props);
			ARRAY_SIZE(charge_battery_props);
	} else if (battery->full_charge_capacity == 0) {
	} else if (!ACPI_BATTERY_CAPACITY_VALID(
					battery->full_charge_capacity)) {
		battery->bat_desc.properties =
		battery->bat_desc.properties =
			energy_battery_full_cap_broken_props;
			energy_battery_full_cap_broken_props;
		battery->bat_desc.num_properties =
		battery->bat_desc.num_properties =