Allow installing some battery firmware updates when the power is too low

The firmware in this case fixes the battery charging, and as the battery is
*internal* the user isn't able to apply the fix.

Fixes https://github.com/fwupd/firmware-lenovo/issues/315
This commit is contained in:
Richard Hughes 2023-02-15 15:43:28 +00:00 committed by Mario Limonciello
parent af862c615d
commit f10dbf9b5d
4 changed files with 22 additions and 2 deletions

View File

@ -239,6 +239,8 @@ fu_device_internal_flag_to_string(FuDeviceInternalFlags flag)
return "auto-pause-polling";
if (flag == FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG)
return "only-wait-for-replug";
if (flag == FU_DEVICE_INTERNAL_FLAG_IGNORE_SYSTEM_POWER)
return "ignore-system-power";
return NULL;
}
@ -307,6 +309,8 @@ fu_device_internal_flag_from_string(const gchar *flag)
return FU_DEVICE_INTERNAL_AUTO_PAUSE_POLLING;
if (g_strcmp0(flag, "only-wait-for-replug") == 0)
return FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG;
if (g_strcmp0(flag, "ignore-system-power") == 0)
return FU_DEVICE_INTERNAL_FLAG_IGNORE_SYSTEM_POWER;
return FU_DEVICE_INTERNAL_FLAG_UNKNOWN;
}

View File

@ -470,6 +470,16 @@ typedef guint64 FuDeviceInternalFlags;
*/
#define FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG (1ull << 25)
/**
* FU_DEVICE_INTERNAL_FLAG_IGNORE_SYSTEM_POWER:
*
* Allow updating firmware when the system power is otherwise too low.
* This is only really useful when updating the system battery firmware.
*
* Since: 1.8.11
*/
#define FU_DEVICE_INTERNAL_FLAG_IGNORE_SYSTEM_POWER (1ull << 26)
/* accessors */
gchar *
fu_device_to_string(FuDevice *self);

View File

@ -30,6 +30,10 @@ Flags = no-coalesce
[90706264-e399-575b-a9fb-077ead03b9b4]
Flags = no-coalesce
# Lenovo T14 Gen 2 Battery
[f7576b01-100e-4ec1-96cf-ccb69f4ce87e]
Flags = ignore-system-power
# Dynabook (né Toshiba) X30, X40
[28108d08-5027-42c2-a5b8-92d6ede9b97b]
VersionFormat = bcd

View File

@ -449,7 +449,8 @@ fu_engine_ensure_device_battery_inhibit(FuEngine *self, FuDevice *device)
} else {
fu_device_remove_problem(device, FWUPD_DEVICE_PROBLEM_REQUIRE_AC_POWER);
}
if (fu_context_get_battery_level(self->ctx) != FWUPD_BATTERY_LEVEL_INVALID &&
if (!fu_device_has_internal_flag(device, FU_DEVICE_INTERNAL_FLAG_IGNORE_SYSTEM_POWER) &&
fu_context_get_battery_level(self->ctx) != FWUPD_BATTERY_LEVEL_INVALID &&
fu_context_get_battery_threshold(self->ctx) != FWUPD_BATTERY_LEVEL_INVALID &&
fu_context_get_battery_level(self->ctx) < fu_context_get_battery_threshold(self->ctx)) {
fu_device_add_problem(device, FWUPD_DEVICE_PROBLEM_SYSTEM_POWER_TOO_LOW);
@ -3485,7 +3486,8 @@ fu_engine_device_check_power(FuEngine *self,
}
/* not enough just in case */
if (fu_context_get_battery_level(self->ctx) != FWUPD_BATTERY_LEVEL_INVALID &&
if (!fu_device_has_internal_flag(device, FU_DEVICE_INTERNAL_FLAG_IGNORE_SYSTEM_POWER) &&
fu_context_get_battery_level(self->ctx) != FWUPD_BATTERY_LEVEL_INVALID &&
fu_context_get_battery_threshold(self->ctx) != FWUPD_BATTERY_LEVEL_INVALID &&
fu_context_get_battery_level(self->ctx) < fu_context_get_battery_threshold(self->ctx)) {
g_set_error(error,