summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorJonathan Brandmeyer <jbrandmeyer@chromium.org>2018-07-16 15:02:22 -0600
committerchrome-bot <chrome-bot@chromium.org>2018-07-26 04:07:41 -0700
commitdda2f778befed39e449d96b471b94d489ed23d60 (patch)
treefc0db938c092a609fbf47e9758d8f0113e5b0cce /power
parent48113728b689870e6aeda6534d36eeffd3b738b3 (diff)
downloadchrome-ec-dda2f778befed39e449d96b471b94d489ed23d60.tar.gz
reset: Log the reason for AP resets.
Provides a new EC host command 'uptime info' which gathers up some information which may be useful for debugging spurious resets on the AP (was the EC reset recently? Why was the EC reset? If the EC reset the AP, why did it do so?, etc.). Provide ectool support for the same. Example results of `ectool uptimeinfo`: ``` localhost ~ # ectool uptimeinfo EC uptime: 475.368 seconds AP resets since EC boot: 2 Most recent AP reset causes: 315.903: reset: console command 363.507: reset: keyboard warm reboot EC reset flags at last EC boot: reset-pin | sysjump ``` BRANCH=none TEST=Perform some `apreset` commands from the EC console and observe their side-effects via the `ectool uptimeinfo` command on the AP side. Test sequences include no-resets through 5 resets, observing that the ring buffer handling was correct. BUG=b:110788201, b:79529789 Signed-off-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Change-Id: I0bf29d69de471c64f905ee8aa070b15b4f34f2ba Reviewed-on: https://chromium-review.googlesource.com/1139028 Commit-Ready: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Tested-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'power')
-rw-r--r--power/apollolake.c8
-rw-r--r--power/braswell.c18
-rw-r--r--power/cannonlake.c7
-rw-r--r--power/intel_x86.c19
-rw-r--r--power/mt817x.c13
-rw-r--r--power/mt8183.c28
-rw-r--r--power/rk3288.c12
-rw-r--r--power/rk3399.c17
-rw-r--r--power/sdm845.c14
-rw-r--r--power/skylake.c3
-rw-r--r--power/stoney.c8
11 files changed, 92 insertions, 55 deletions
diff --git a/power/apollolake.c b/power/apollolake.c
index dda74a29b9..a9ac1c06d9 100644
--- a/power/apollolake.c
+++ b/power/apollolake.c
@@ -6,6 +6,7 @@
/* Apollolake chipset power control module for Chrome EC */
#include "apollolake.h"
+#include "chipset.h"
#include "console.h"
#include "gpio.h"
#include "intel_x86.h"
@@ -42,8 +43,11 @@ static void internal_chipset_shutdown(void)
chipset_do_shutdown();
}
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
+ CPRINTS("%s: %d", __func__, reason);
+ report_ap_reset(reason);
+
/*
* This function is called from multiple tasks and hence it is racy! But
* since things are going down hard, it does not matter if some task
@@ -55,7 +59,7 @@ void chipset_force_shutdown(void)
enum power_state chipset_force_g3(void)
{
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_G3);
return POWER_G3;
}
diff --git a/power/braswell.c b/power/braswell.c
index e04918c055..4140c02adf 100644
--- a/power/braswell.c
+++ b/power/braswell.c
@@ -53,9 +53,10 @@
static int throttle_cpu; /* Throttle CPU? */
static int forcing_shutdown; /* Forced shutdown in progress? */
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
- CPRINTS("%s()", __func__);
+ CPRINTS("%s(%d)", __func__, reason);
+ report_ap_reset(reason);
/*
* Force power off. This condition will reset once the state machine
@@ -68,9 +69,10 @@ void chipset_force_shutdown(void)
forcing_shutdown = 1;
}
-void chipset_reset(void)
+void chipset_reset(enum chipset_reset_reason reason)
{
- CPRINTS("%s", __func__);
+ CPRINTS("%s: %d", __func__, reason);
+ report_ap_reset(reason);
/*
* Send a reset pulse to the PCH. This just causes it to
@@ -138,7 +140,7 @@ enum power_state power_handle_state(enum power_state state)
CPRINTS("Exit SOC G3");
if (power_wait_signals(IN_PGOOD_S5)) {
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
return POWER_G3;
}
@@ -165,7 +167,7 @@ enum power_state power_handle_state(enum power_state state)
/* Check for state transitions */
if (!power_has_signals(IN_PGOOD_S3)) {
/* Required rail went away */
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
return POWER_S3S5;
} else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1) {
/* Power up to next state */
@@ -182,7 +184,7 @@ enum power_state power_handle_state(enum power_state state)
/*wireless_set_state(WIRELESS_ON);*/
if (!power_has_signals(IN_PGOOD_S3)) {
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
/*wireless_set_state(WIRELESS_OFF);*/
return POWER_S3S5;
@@ -222,7 +224,7 @@ enum power_state power_handle_state(enum power_state state)
case POWER_S0:
if (!power_has_signals(IN_PGOOD_ALWAYS_ON)) {
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
return POWER_S0S3;
}
diff --git a/power/cannonlake.c b/power/cannonlake.c
index 47b1c912f0..1822b1d3c2 100644
--- a/power/cannonlake.c
+++ b/power/cannonlake.c
@@ -20,9 +20,9 @@
static int forcing_shutdown; /* Forced shutdown in progress? */
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
- CPRINTS("%s()", __func__);
+ CPRINTS("%s(%d)", __func__, reason);
/*
* Force off. Sending a reset command to the PMIC will power off
@@ -32,6 +32,7 @@ void chipset_force_shutdown(void)
* hold time on the PMIC.
*/
if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
+ report_ap_reset(reason);
forcing_shutdown = 1;
power_button_pch_press();
}
@@ -55,7 +56,7 @@ void chipset_handle_espi_reset_assert(void)
enum power_state chipset_force_g3(void)
{
int timeout = 50;
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_G3);
/* Turn off DSW load switch. */
gpio_set_level(GPIO_EN_PP3300_DSW, 0);
diff --git a/power/intel_x86.c b/power/intel_x86.c
index 1cc8beadf5..15c1cf1b4a 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -219,7 +219,7 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
case POWER_S3:
if (!power_has_signals(IN_PGOOD_ALL_CORE)) {
/* Required rail went away */
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
return POWER_S3S5;
} else if (chipset_get_sleep_signal(SYS_SLEEP_S3) == 1) {
/* Power up to next state */
@@ -232,7 +232,7 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
case POWER_S0:
if (!power_has_signals(IN_PGOOD_ALL_CORE)) {
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
return POWER_S0S3;
} else if (chipset_get_sleep_signal(SYS_SLEEP_S3) == 0) {
/* Power down to next state */
@@ -293,7 +293,8 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
if (tries == CHARGER_INITIALIZED_TRIES) {
CPRINTS("power-up inhibited");
power_up_inhibited = 1;
- chipset_force_shutdown();
+ chipset_force_shutdown(
+ CHIPSET_SHUTDOWN_BATTERY_INHIBIT);
return POWER_G3;
}
@@ -320,7 +321,7 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
#endif
if (power_wait_signals(CHIPSET_G3S5_POWERUP_SIGNAL)) {
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
return POWER_G3;
}
@@ -330,7 +331,7 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
case POWER_S5S3:
if (!power_has_signals(IN_PGOOD_ALL_CORE)) {
/* Required rail went away */
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
return POWER_S5G3;
}
@@ -349,7 +350,7 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
case POWER_S3S0:
if (!power_has_signals(IN_PGOOD_ALL_CORE)) {
/* Required rail went away */
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
return POWER_S3S5;
}
@@ -563,7 +564,7 @@ void power_chipset_handle_host_sleep_event(enum host_sleep_event state)
#endif
-void chipset_reset(void)
+void chipset_reset(enum chipset_reset_reason reason)
{
/*
* Irrespective of cold_reset value, always toggle SYS_RESET_L to
@@ -574,7 +575,7 @@ void chipset_reset(void)
* The EC cannot control warm vs cold reset of the chipset using
* SYS_RESET_L; it's more of a request.
*/
- CPRINTS("%s", __func__);
+ CPRINTS("%s: %d", __func__, reason);
/*
* Toggling SYS_RESET_L will not have any impact when it's already
@@ -585,6 +586,8 @@ void chipset_reset(void)
return;
}
+ report_ap_reset(reason);
+
gpio_set_level(GPIO_SYS_RESET_L, 0);
/*
* Debounce time for SYS_RESET_L is 16 ms. Wait twice that period
diff --git a/power/mt817x.c b/power/mt817x.c
index 37db9fe698..f13e04a1e3 100644
--- a/power/mt817x.c
+++ b/power/mt817x.c
@@ -418,7 +418,7 @@ enum power_state power_chipset_init(void)
* The warm reset triggers AP into the recovery mode (
* flash SPI from USB).
*/
- chipset_reset();
+ chipset_reset(CHIPSET_RESET_UNKNOWN);
init_power_state = POWER_G3;
} else {
@@ -474,8 +474,11 @@ static void chipset_turn_off_power_rails(void)
set_system_power(0);
}
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
+ CPRINTS("%s: %d", __func__, reason);
+ report_ap_reset(reason);
+
chipset_turn_off_power_rails();
/* clean-up internal variable */
@@ -638,9 +641,11 @@ static void power_on(void)
CPRINTS("AP running ...");
}
-void chipset_reset(void)
+void chipset_reset(enum chipset_reset_reason reason)
{
- CPRINTS("EC triggered warm reboot");
+ CPRINTS("%s: %d", __func__, reason);
+ report_ap_reset(reason);
+
set_warm_reset(1);
usleep(PMIC_WARM_RESET_H_HOLD_TIME);
/* deassert the reset signals */
diff --git a/power/mt8183.c b/power/mt8183.c
index 7e8d5ba57b..13a76532a2 100644
--- a/power/mt8183.c
+++ b/power/mt8183.c
@@ -89,9 +89,10 @@ static const struct power_seq_op s3s5_power_seq[] = {
static int forcing_shutdown;
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
- CPRINTS("%s()", __func__);
+ CPRINTS("%s(%d)", __func__, reason);
+ report_ap_reset(reason);
/*
* Force power off. This condition will reset once the state machine
@@ -100,12 +101,18 @@ void chipset_force_shutdown(void)
forcing_shutdown = 1;
task_wake(TASK_ID_CHIPSET);
}
-DECLARE_DEFERRED(chipset_force_shutdown);
+
+void chipset_force_shutdown_button(void)
+{
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_BUTTON);
+}
+DECLARE_DEFERRED(chipset_force_shutdown_button);
/* If chipset needs to be reset, EC also reboots to RO. */
-void chipset_reset(void)
+void chipset_reset(enum chipset_reset_reason reason)
{
- CPRINTS("%s", __func__);
+ CPRINTS("%s: %d", __func__, reason);
+ report_ap_reset(reason);
cflush();
system_reset(SYSTEM_RESET_HARD);
@@ -214,7 +221,7 @@ enum power_state power_handle_state(enum power_state state)
* after debounce (32 ms), minus PMIC_EN_PULSE_MS above.
* It would be good to avoid another _EN pulse above.
*/
- chipset_reset();
+ chipset_reset(CHIPSET_RESET_INIT);
}
/* Wait for PMIC to bring up rails. */
@@ -238,7 +245,7 @@ enum power_state power_handle_state(enum power_state state)
power_seq_run(s3s0_power_seq, ARRAY_SIZE(s3s0_power_seq));
if (power_wait_signals(IN_PGOOD_S0)) {
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
return POWER_S0S3;
}
@@ -277,7 +284,8 @@ enum power_state power_handle_state(enum power_state state)
*/
if (power_button_is_pressed()) {
forcing_shutdown = 1;
- hook_call_deferred(&chipset_force_shutdown_data, -1);
+ hook_call_deferred(&chipset_force_shutdown_button_data,
+ -1);
}
return POWER_S3;
@@ -306,11 +314,11 @@ static void power_button_changed(void)
chipset_exit_hard_off();
/* Delayed power down from S0/S3, cancel on PB release */
- hook_call_deferred(&chipset_force_shutdown_data,
+ hook_call_deferred(&chipset_force_shutdown_button_data,
FORCED_SHUTDOWN_DELAY);
} else {
/* Power button released, cancel deferred shutdown */
- hook_call_deferred(&chipset_force_shutdown_data, -1);
+ hook_call_deferred(&chipset_force_shutdown_button_data, -1);
}
}
DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, power_button_changed, HOOK_PRIO_DEFAULT);
diff --git a/power/rk3288.c b/power/rk3288.c
index 22ec8eff5b..8144401b54 100644
--- a/power/rk3288.c
+++ b/power/rk3288.c
@@ -223,7 +223,7 @@ enum power_state power_chipset_init(void)
* The warm reset triggers AP into the RK recovery mode (
* flash SPI from USB).
*/
- chipset_reset();
+ chipset_reset(CHIPSET_RESET_INIT);
init_power_state = POWER_G3;
} else {
@@ -265,8 +265,10 @@ static void chipset_turn_off_power_rails(void)
set_pmic_warm_reset(1);
}
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
+ CPRINTS("%s(%d)", __func__, reason);
+ report_ap_reset(reason);
chipset_turn_off_power_rails();
/* clean-up internal variable */
@@ -380,9 +382,11 @@ static void power_off(void)
CPRINTS("power shutdown complete");
}
-void chipset_reset(void)
+void chipset_reset(enum chipset_reset_reason reason)
{
- CPRINTS("EC triggered warm reboot");
+ CPRINTS("%s(%d)", __func__, reason);
+ report_ap_reset(reason);
+
CPRINTS("assert GPIO_PMIC_WARM_RESET_L for %d ms",
PMIC_WARM_RESET_L_HOLD_TIME / MSEC);
set_pmic_warm_reset(1);
diff --git a/power/rk3399.c b/power/rk3399.c
index e70bd3e84f..b229684e7a 100644
--- a/power/rk3399.c
+++ b/power/rk3399.c
@@ -207,9 +207,10 @@ static const struct power_seq_op s3s5_power_seq[] = {
static int forcing_shutdown;
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
- CPRINTS("%s()", __func__);
+ CPRINTS("%s(%d)", __func__, reason);
+ report_ap_reset(reason);
/*
* Force power off. This condition will reset once the state machine
@@ -220,13 +221,14 @@ void chipset_force_shutdown(void)
}
#define SYS_RST_HOLD_US (1 * MSEC)
-void chipset_reset(void)
+void chipset_reset(enum chipset_reset_reason reason)
{
#ifdef CONFIG_CMD_RTC
/* Print out the RTC to help correlate resets in logs. */
print_system_rtc(CC_CHIPSET);
#endif
- CPRINTS("%s", __func__);
+ CPRINTS("%s(%d)", __func__, reason);
+ report_ap_reset(reason);
/* Pulse SYS_RST */
gpio_set_level(GPIO_SYS_RST_L, 0);
@@ -389,7 +391,8 @@ enum power_state power_handle_state(enum power_state state)
if (charge_want_shutdown() ||
tries > CHARGER_INITIALIZED_TRIES) {
CPRINTS("power-up inhibited");
- chipset_force_shutdown();
+ chipset_force_shutdown(
+ CHIPSET_SHUTDOWN_BATTERY_INHIBIT);
return POWER_G3;
}
@@ -408,7 +411,7 @@ enum power_state power_handle_state(enum power_state state)
#endif
if (power_wait_signals(IN_PGOOD_S3)) {
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
return POWER_S3S5;
}
@@ -458,7 +461,7 @@ enum power_state power_handle_state(enum power_state state)
#else
if (power_wait_signals(IN_PGOOD_S0)) {
#endif /* POWER_SIGNAL_POLLING */
- chipset_force_shutdown();
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
return POWER_S0S3;
}
diff --git a/power/sdm845.c b/power/sdm845.c
index f6a22c54ae..350e940504 100644
--- a/power/sdm845.c
+++ b/power/sdm845.c
@@ -141,7 +141,7 @@ enum power_on_event_t {
static void chipset_reset_request_handler(void)
{
CPRINTS("AP wants reset");
- chipset_reset();
+ chipset_reset(CHIPSET_RESET_AP_REQ);
}
DECLARE_DEFERRED(chipset_reset_request_handler);
@@ -582,22 +582,26 @@ static int check_for_power_off_event(void)
/*****************************************************************************/
/* Chipset interface */
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
- CPRINTS("EC triggered shutdown");
+ CPRINTS("%s(%d)", __func__, reason);
+ report_ap_reset(reason);
+
power_off();
/* Clean-up internal variable */
power_request = POWER_REQ_NONE;
}
-void chipset_reset(void)
+void chipset_reset(enum chipset_reset_reason reason)
{
/*
* Before we can reprogram the PMIC to make the PMIC RESIN_N pin as
* reset pin and zero-latency. We do cold reset instead.
*/
- CPRINTS("EC triggered cold reboot");
+ CPRINTS("%s(%d)", __func__, reason);
+ report_ap_reset(reason);
+
bypass_power_lost_trigger = 1;
power_off();
bypass_power_lost_trigger = 0;
diff --git a/power/skylake.c b/power/skylake.c
index 8df01c542f..a5cf6aa0a5 100644
--- a/power/skylake.c
+++ b/power/skylake.c
@@ -23,7 +23,7 @@
static int forcing_shutdown; /* Forced shutdown in progress? */
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
CPRINTS("%s()", __func__);
@@ -35,6 +35,7 @@ void chipset_force_shutdown(void)
* hold time on the PMIC.
*/
if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
+ report_ap_reset(reason);
forcing_shutdown = 1;
power_button_pch_press();
}
diff --git a/power/stoney.c b/power/stoney.c
index 3034eee41e..1cc08de9fc 100644
--- a/power/stoney.c
+++ b/power/stoney.c
@@ -30,13 +30,14 @@
static int forcing_shutdown; /* Forced shutdown in progress? */
-void chipset_force_shutdown(void)
+void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
CPRINTS("%s()", __func__);
if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
forcing_shutdown = 1;
power_button_pch_press();
+ report_ap_reset(reason);
}
}
@@ -46,15 +47,16 @@ static void chipset_force_g3(void)
gpio_set_level(GPIO_EN_PWR_A, 0);
}
-void chipset_reset(void)
+void chipset_reset(enum chipset_reset_reason reason)
{
- CPRINTS("%s", __func__);
+ CPRINTS("%s: %d", __func__, reason);
if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
CPRINTS("Can't reset: SOC is off");
return;
}
+ report_ap_reset(reason);
/*
* Send a pulse to SYS_RST to trigger a warm reset.
*/