/* SPDX-License-Identifier: GPL-2.0-only */ #include #include #include #include #include #include #include static int get_index_bit(uint32_t value, uint16_t limit) { uint16_t i; uint32_t t; if (limit >= TOTAL_BITS(uint32_t)) return -1; /* get a mask of valid bits. Ex limit = 3, set bits 0-2 */ t = (1 << limit) - 1; if ((value & t) == 0) return -1; t = 1; for (i = 0; i < limit; i++) { if (value & t) break; t <<= 1; } return i; } static void pm_fill_gnvs(struct global_nvs *gnvs, const struct acpi_pm_gpe_state *state) { int index; index = get_index_bit(state->pm1_sts & state->pm1_en, PM1_LIMIT); if (index < 0) gnvs->pm1i = ~0ULL; else gnvs->pm1i = index; index = get_index_bit(state->gpe0_sts & state->gpe0_en, GPE0_LIMIT); if (index < 0) gnvs->gpei = ~0ULL; else gnvs->gpei = index; } static void acpi_save_wake_source(void *unused) { const struct chipset_power_state *ps; struct global_nvs *gnvs = acpi_get_gnvs(); if (!gnvs) return; if (acpi_pm_state_for_wake(&ps) < 0) return; pm_fill_gnvs(gnvs, &ps->gpe_state); } BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, acpi_save_wake_source, NULL);