|
@@ -95,6 +95,7 @@ enum {
|
|
|
* due to bad math.
|
|
|
*/
|
|
|
ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
|
|
|
+ ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
|
|
|
};
|
|
|
|
|
|
struct acpi_battery {
|
|
@@ -405,6 +406,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
|
|
|
result = extract_package(battery, buffer.pointer,
|
|
|
info_offsets, ARRAY_SIZE(info_offsets));
|
|
|
kfree(buffer.pointer);
|
|
|
+ if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
|
|
+ battery->full_charge_capacity = battery->design_capacity;
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -441,6 +444,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
|
|
|
battery->rate_now != -1)
|
|
|
battery->rate_now = abs((s16)battery->rate_now);
|
|
|
|
|
|
+ if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
|
|
|
+ && battery->capacity_now >= 0 && battery->capacity_now <= 100)
|
|
|
+ battery->capacity_now = (battery->capacity_now *
|
|
|
+ battery->full_charge_capacity) / 100;
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -552,6 +559,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * According to the ACPI spec, some kinds of primary batteries can
|
|
|
+ * report percentage battery remaining capacity directly to OS.
|
|
|
+ * In this case, it reports the Last Full Charged Capacity == 100
|
|
|
+ * and BatteryPresentRate == 0xFFFFFFFF.
|
|
|
+ *
|
|
|
+ * Now we found some battery reports percentage remaining capacity
|
|
|
+ * even if it's rechargeable.
|
|
|
+ * https://bugzilla.kernel.org/show_bug.cgi?id=15979
|
|
|
+ *
|
|
|
+ * Handle this correctly so that they won't break userspace.
|
|
|
+ */
|
|
|
+static void acpi_battery_quirks2(struct acpi_battery *battery)
|
|
|
+{
|
|
|
+ if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
|
|
+ return ;
|
|
|
+
|
|
|
+ if (battery->full_charge_capacity == 100 &&
|
|
|
+ battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
|
|
|
+ battery->capacity_now >=0 && battery->capacity_now <= 100) {
|
|
|
+ set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
|
|
|
+ battery->full_charge_capacity = battery->design_capacity;
|
|
|
+ battery->capacity_now = (battery->capacity_now *
|
|
|
+ battery->full_charge_capacity) / 100;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int acpi_battery_update(struct acpi_battery *battery)
|
|
|
{
|
|
|
int result, old_present = acpi_battery_present(battery);
|
|
@@ -573,7 +607,9 @@ static int acpi_battery_update(struct acpi_battery *battery)
|
|
|
}
|
|
|
if (!battery->bat.dev)
|
|
|
sysfs_add_battery(battery);
|
|
|
- return acpi_battery_get_state(battery);
|
|
|
+ result = acpi_battery_get_state(battery);
|
|
|
+ acpi_battery_quirks2(battery);
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/* --------------------------------------------------------------------------
|