summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/stm32/keyboard_scan.c25
-rw-r--r--common/gaia_power.c27
-rw-r--r--include/system.h3
3 files changed, 55 insertions, 0 deletions
diff --git a/chip/stm32/keyboard_scan.c b/chip/stm32/keyboard_scan.c
index 350439ef1e..de537cc931 100644
--- a/chip/stm32/keyboard_scan.c
+++ b/chip/stm32/keyboard_scan.c
@@ -64,6 +64,16 @@ static const uint8_t actual_key_masks[4][KB_OUTPUTS] = {
#define MASK_INDEX_REFRESH 2
#define MASK_VALUE_REFRESH 0x04
+/* Key masks and values for warm reboot combination */
+#define MASK_INDEX_KEYR 3
+#define MASK_VALUE_KEYR 0x80
+#define MASK_INDEX_VOL_UP 4
+#define MASK_VALUE_VOL_UP 0x01
+#define MASK_INDEX_RIGHT_ALT 10
+#define MASK_VALUE_RIGHT_ALT 0x01
+#define MASK_INDEX_LEFT_ALT 10
+#define MASK_VALUE_LEFT_ALT 0x40
+
struct kbc_gpio {
int num; /* logical row or column number */
uint32_t port;
@@ -217,6 +227,16 @@ void enter_polling_mode(void)
select_column(COL_TRI_STATE_ALL);
}
+static int check_warm_reboot_keys(void)
+{
+ if (raw_state[MASK_INDEX_KEYR] == MASK_VALUE_KEYR &&
+ raw_state[MASK_INDEX_VOL_UP] == MASK_VALUE_VOL_UP &&
+ (raw_state[MASK_INDEX_RIGHT_ALT] == MASK_VALUE_RIGHT_ALT ||
+ raw_state[MASK_INDEX_LEFT_ALT] == MASK_VALUE_LEFT_ALT))
+ return 1;
+
+ return 0;
+}
/* Returns 1 if any key is still pressed. 0 if no key is pressed. */
static int check_keys_changed(void)
@@ -295,6 +315,11 @@ static int check_keys_changed(void)
}
CPUTS("]\n");
+ if (num_press == 3) {
+ if (check_warm_reboot_keys())
+ system_warm_reboot();
+ }
+
if (kb_fifo_add(raw_state) == EC_SUCCESS)
board_interrupt_host(1);
else
diff --git a/common/gaia_power.c b/common/gaia_power.c
index 2ef6f3ddf5..a3de5b91df 100644
--- a/common/gaia_power.c
+++ b/common/gaia_power.c
@@ -588,3 +588,30 @@ DECLARE_CONSOLE_COMMAND(power, command_power,
"on/off",
"Turn AP power on/off",
NULL);
+
+void system_warm_reboot(void)
+{
+ CPRINTF("[%T EC triggered warm reboot ]\n");
+
+ /* This is a hack to do an AP warm reboot while still preserving
+ * RAM contents. This is useful for looking at kernel log message
+ * contents from previous boot in cases where the AP/OS is hard
+ * hung. */
+ gpio_set_level(GPIO_EN_PP5000, 0);
+ gpio_set_level(GPIO_EN_PP3300, 0);
+
+ power_request = POWER_REQ_ON;
+ task_wake(TASK_ID_GAIAPOWER);
+
+ return;
+}
+
+static int command_warm_reboot(int argc, char **argv)
+{
+ system_warm_reboot();
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(warm_reboot, command_warm_reboot,
+ NULL,
+ "EC triggered warm reboot",
+ NULL);
diff --git a/include/system.h b/include/system.h
index c11e89814d..f3d5b035d6 100644
--- a/include/system.h
+++ b/include/system.h
@@ -156,6 +156,9 @@ const char *system_get_build_info(void);
void system_reset(int flags);
+/* System warm reboot while keeping the RAM alive. */
+void system_warm_reboot(void);
+
/* Set a scratchpad register to the specified value. The scratchpad
* register must maintain its contents across a software-requested
* warm reset. */