diff options
-rw-r--r-- | src/ec/google/chromeec/ec.c | 83 | ||||
-rw-r--r-- | src/ec/google/chromeec/ec.h | 6 | ||||
-rw-r--r-- | src/ec/google/chromeec/smihandler.c | 18 | ||||
-rw-r--r-- | src/ec/google/chromeec/smm.h | 7 |
4 files changed, 113 insertions, 1 deletions
diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index de17495ff6..2efc66a77c 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -24,7 +24,6 @@ #include <elog.h> #include <halt.h> #include <reset.h> -#include <elog.h> #include <rtc.h> #include <stdlib.h> #include <vboot/vboot_common.h> @@ -161,6 +160,88 @@ int google_chromeec_clear_events_b(u32 mask) EC_CMD_HOST_EVENT_CLEAR_B, mask); } +/* Get the current device event mask */ +uint32_t google_chromeec_get_device_enabled_events(void) +{ + struct ec_params_device_event req; + struct ec_response_device_event rsp; + struct chromeec_command cmd; + + req.param = EC_DEVICE_EVENT_PARAM_GET_ENABLED_EVENTS; + cmd.cmd_code = EC_CMD_DEVICE_EVENT; + cmd.cmd_version = 0; + cmd.cmd_data_in = &req; + cmd.cmd_size_in = sizeof(req); + cmd.cmd_data_out = &rsp; + cmd.cmd_size_out = sizeof(rsp); + cmd.cmd_dev_index = 0; + + if (google_chromeec_command(&cmd) == 0) + return rsp.event_mask; + return 0; +} + +/* Set the current device event mask */ +int google_chromeec_set_device_enabled_events(uint32_t mask) +{ + struct ec_params_device_event req; + struct ec_response_device_event rsp; + struct chromeec_command cmd; + + req.event_mask = mask; + req.param = EC_DEVICE_EVENT_PARAM_SET_ENABLED_EVENTS; + cmd.cmd_code = EC_CMD_DEVICE_EVENT; + cmd.cmd_version = 0; + cmd.cmd_data_in = &req; + cmd.cmd_size_in = sizeof(req); + cmd.cmd_data_out = &rsp; + cmd.cmd_size_out = sizeof(rsp); + cmd.cmd_dev_index = 0; + + return google_chromeec_command(&cmd); +} + +/* Read and clear pending device events */ +uint32_t google_chromeec_get_device_current_events(void) +{ + struct ec_params_device_event req; + struct ec_response_device_event rsp; + struct chromeec_command cmd; + + req.param = EC_DEVICE_EVENT_PARAM_GET_CURRENT_EVENTS; + cmd.cmd_code = EC_CMD_DEVICE_EVENT; + cmd.cmd_version = 0; + cmd.cmd_data_in = &req; + cmd.cmd_size_in = sizeof(req); + cmd.cmd_data_out = &rsp; + cmd.cmd_size_out = sizeof(rsp); + cmd.cmd_dev_index = 0; + + if (google_chromeec_command(&cmd) == 0) + return rsp.event_mask; + return 0; +} + +void google_chromeec_log_device_events(uint32_t mask) +{ + uint32_t events; + int i; + + if (!IS_ENABLED(CONFIG_ELOG)) + return; + + if (google_chromeec_check_feature(EC_FEATURE_DEVICE_EVENT) != 1) + return; + + events = google_chromeec_get_device_current_events() & mask; + printk(BIOS_INFO, "EC Device Events: 0x%08x\n", events); + + for (i = 0; i < sizeof(events) * 8; i++) { + if (EC_DEVICE_EVENT_MASK(i) & events) + elog_add_event_byte(ELOG_TYPE_EC_DEVICE_EVENT, i); + } +} + int google_chromeec_check_feature(int feature) { struct chromeec_command cmd; diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index 4a45f7f4ab..b2b63e8e5f 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -34,6 +34,12 @@ u8 google_chromeec_get_event(void); int google_ec_running_ro(void); void google_chromeec_init(void); +/* Device events */ +uint32_t google_chromeec_get_device_enabled_events(void); +int google_chromeec_set_device_enabled_events(uint32_t mask); +uint32_t google_chromeec_get_device_current_events(void); +void google_chromeec_log_device_events(uint32_t mask); + /* If recovery mode is enabled and EC is not running RO firmware reboot. */ void google_chromeec_early_init(void); /* Reboot if EC firmware is not expected type. */ diff --git a/src/ec/google/chromeec/smihandler.c b/src/ec/google/chromeec/smihandler.c index 75636ea8c1..379ff68019 100644 --- a/src/ec/google/chromeec/smihandler.c +++ b/src/ec/google/chromeec/smihandler.c @@ -73,6 +73,24 @@ void chromeec_smi_sleep(int slp_type, uint32_t s3_mask, uint32_t s5_mask) clear_pending_events(); } +void chromeec_smi_device_event_sleep(int slp_type, uint32_t s3_mask, + uint32_t s5_mask) +{ + switch (slp_type) { + case ACPI_S3: + /* Enable device wake events */ + google_chromeec_set_device_enabled_events(s3_mask); + break; + case ACPI_S5: + /* Enable device wake events */ + google_chromeec_set_device_enabled_events(s5_mask); + break; + } + + /* Read and clear pending events that may trigger immediate wake */ + google_chromeec_get_device_current_events(); +} + void chromeec_smi_apmc(int apmc, uint32_t sci_mask, uint32_t smi_mask) { switch (apmc) { diff --git a/src/ec/google/chromeec/smm.h b/src/ec/google/chromeec/smm.h index 03d6e0044f..8265cddcfd 100644 --- a/src/ec/google/chromeec/smm.h +++ b/src/ec/google/chromeec/smm.h @@ -28,6 +28,13 @@ void chromeec_smi_process_events(void); void chromeec_smi_sleep(int slp_type, uint32_t s3_mask, uint32_t s5_mask); /* + * Set device event masks according to sleep type, + * and clear any pending device events. + */ +void chromeec_smi_device_event_sleep(int slp_type, uint32_t s3_mask, + uint32_t s5_mask); + +/* * Provided the APMC command do the following while clearing pending events. * APM_CNT_ACPI_ENABLE: clear SMI mask. set SCI mask. * APM_CNT_ACPI_DISABLE: clear SCI mask. set SMI mask. |