diff options
-rw-r--r-- | common/acpi.c | 5 | ||||
-rw-r--r-- | common/thermal.c | 23 | ||||
-rw-r--r-- | include/dptf.h | 6 | ||||
-rw-r--r-- | include/ec_commands.h | 8 |
4 files changed, 37 insertions, 5 deletions
diff --git a/common/acpi.c b/common/acpi.c index 68c281b6e6..69cf3bc837 100644 --- a/common/acpi.c +++ b/common/acpi.c @@ -71,6 +71,11 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr) result = dptf_get_fan_duty_target(); break; #endif +#ifdef CONFIG_TEMP_SENSOR + case EC_ACPI_MEM_TEMP_ID: + result = dptf_query_next_sensor_event(); + break; +#endif default: CPRINTF("[%T ACPI read 0x%02x (ignored)]\n", acpi_addr); break; diff --git a/common/thermal.c b/common/thermal.c index 6464ef7161..7113564f82 100644 --- a/common/thermal.c +++ b/common/thermal.c @@ -7,6 +7,7 @@ * implementation from the original version that shipped on Link. */ +#include "atomic.h" #include "chipset.h" #include "common.h" #include "console.h" @@ -45,8 +46,21 @@ static void dptf_init(void) } DECLARE_HOOK(HOOK_INIT, dptf_init, HOOK_PRIO_DEFAULT); +/* Keep track of which triggered sensor thresholds the AP has seen */ +static uint32_t dptf_seen; +int dptf_query_next_sensor_event(void) +{ + int id; + for (id = 0; id < TEMP_SENSOR_COUNT; id++) + if (dptf_seen & (1 << id)) { /* atomic? */ + atomic_clear(&dptf_seen, (1 << id)); + return id; + } + + return -1; +} /* Return true if any threshold transition occurs. */ static int dpft_check_temp_threshold(int sensor_id, int temp) @@ -68,11 +82,13 @@ static int dpft_check_temp_threshold(int sensor_id, int temp) if (cond_went_true(&dptf_threshold[sensor_id][i].over)) { CPRINTF("[%T DPTF over threshold [%d][%d]\n", sensor_id, i); + atomic_or(&dptf_seen, (1 << sensor_id)); tripped = 1; } if (cond_went_false(&dptf_threshold[sensor_id][i].over)) { CPRINTF("[%T DPTF under threshold [%d][%d]\n", sensor_id, i); + atomic_or(&dptf_seen, (1 << sensor_id)); tripped = 1; } } @@ -80,7 +96,6 @@ static int dpft_check_temp_threshold(int sensor_id, int temp) return tripped; } - void dptf_set_temp_threshold(int sensor_id, int temp, int idx, int enable) { CPRINTF("[%T DPTF sensor %d, threshold %d C, index %d, %sabled]\n", @@ -89,15 +104,12 @@ void dptf_set_temp_threshold(int sensor_id, int temp, int idx, int enable) if (enable) { dptf_threshold[sensor_id][idx].temp = temp; cond_init(&dptf_threshold[sensor_id][idx].over, 0); + atomic_clear(&dptf_seen, (1 << sensor_id)); } else { dptf_threshold[sensor_id][idx].temp = -1; } } - - - - /*****************************************************************************/ /* EC-specific thermal controls */ @@ -350,6 +362,7 @@ static int command_dptftemp(int argc, char **argv) ccprintf(" %s\n", temp_sensors[id].name); } + ccprintf("AP seen mask: 0x%08x\n", dptf_seen); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(dptftemp, command_dptftemp, diff --git a/include/dptf.h b/include/dptf.h index 31c9c09bca..f611acb361 100644 --- a/include/dptf.h +++ b/include/dptf.h @@ -24,4 +24,10 @@ void dptf_set_temp_threshold(int sensor_id, /* zero-based sensor index */ int idx, /* which threshold (0 or 1) */ int enable); /* true = on, false = off */ +/* + * Return the ID of a temp sensor that has crossed its threshold since the last + time we asked. -1 means none. + */ +int dptf_query_next_sensor_event(void); + #endif /* __CROS_EC_DPTF_H */ diff --git a/include/ec_commands.h b/include/ec_commands.h index 7b3fb170d1..f526accd00 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -1877,6 +1877,14 @@ struct ec_params_reboot_ec { * register determines which sensor is affected by the THRESHOLD and COMMIT * registers. The THRESHOLD register uses the same EC_TEMP_SENSOR_OFFSET scheme * as the memory-mapped sensors. The COMMIT register applies those settings. + * + * The spec does not mandate any way to read back the threshold settings + * themselves, but when a threshold is crossed the AP needs a way to determine + * which sensor(s) are responsible. Each reading of the ID register clears and + * returns one sensor ID that has crossed one of its threshold (in either + * direction) since the last read. A value of 0xFF means "no new thresholds + * have tripped". Setting or enabling the thresholds for a sensor will clear + * the unread event count for that sensor. */ #define EC_ACPI_MEM_TEMP_ID 0x05 #define EC_ACPI_MEM_TEMP_THRESHOLD 0x06 |