summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/acpi.c5
-rw-r--r--common/thermal.c23
-rw-r--r--include/dptf.h6
-rw-r--r--include/ec_commands.h8
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