From 2fc3036ba8a8eb18142056bb39b0d29e1d4fb88a Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Mon, 14 Mar 2022 16:05:01 +0000 Subject: [PATCH] acpi: extend acpi event listener about power button events Upon receiving acpi event related to ACPI button notification emulate PM/PWRBTN_STS and trigger SCI. BUG=None TEST=After enabling CONFIG_ACPI_BUTTON on hypervisor kernel, check if power button events are propagated to the guest by reading /sys/firmware/acpi/interrupts/ff_pwr_btn counter. Change-Id: Ie52c58d0934fb6657940bdca35dfbc68a8f4f42c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3521728 Reviewed-by: Dmitry Torokhov Tested-by: kokoro Commit-Queue: Tomasz Nowicki --- devices/src/acpi.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/devices/src/acpi.rs b/devices/src/acpi.rs index 806c047917..9b0a707826 100644 --- a/devices/src/acpi.rs +++ b/devices/src/acpi.rs @@ -221,7 +221,13 @@ fn run_worker( for event in events.iter().filter(|e| e.is_readable) { match event.token { Token::AcpiEvent => { - acpi_event_run(&acpi_event_sock, &gpe0, &sci_evt, &acpi_event_ignored_gpe); + acpi_event_run( + &acpi_event_sock, + &gpe0, + &pm1, + &sci_evt, + &acpi_event_ignored_gpe, + ); } Token::InterruptResample => { let _ = sci_resample.read(); @@ -275,6 +281,22 @@ fn acpi_event_gpe_class( } } +const ACPI_BUTTON_NOTIFY_STATUS: u32 = 0x80; + +fn acpi_event_pwrbtn_class( + acpi_event: AcpiNotifyEvent, + pm1: &Arc>, + sci_evt: &Event, +) { + // If received power button event, emulate PM/PWRBTN_STS and trigger SCI + if acpi_event._type == ACPI_BUTTON_NOTIFY_STATUS && acpi_event.bus_id.contains("LNXPWRBN") { + let mut pm1 = pm1.lock(); + + pm1.status |= BITMASK_PM1STS_PWRBTN_STS; + pm1.trigger_sci(sci_evt); + } +} + fn get_acpi_event_group() -> Option { // Create netlink generic socket which will be used to query about given family name let netlink_ctrl_sock = NetlinkGenericSocket::new(0).unwrap(); @@ -288,6 +310,7 @@ fn get_acpi_event_group() -> Option { fn acpi_event_run( acpi_event_sock: &NetlinkGenericSocket, gpe0: &Arc>, + pm1: &Arc>, sci_evt: &Event, ignored_gpe: &[u32], ) { @@ -317,6 +340,7 @@ fn acpi_event_run( ignored_gpe, ); } + "button/power" => acpi_event_pwrbtn_class(acpi_event, pm1, sci_evt), c => warn!("unknown acpi event {}", c), }; }