summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@chromium.org>2017-02-07 17:02:35 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-02-09 20:48:47 -0800
commit4ce529e25acd4683f7232dc627c72cb7f3f84d77 (patch)
tree2da1bbe28b8b102f3fc498bb4cac3128f6039de4
parent11c0c9e86d9f52a71b6a252366ad0ec3f775f858 (diff)
downloadchrome-ec-4ce529e25acd4683f7232dc627c72cb7f3f84d77.tar.gz
chip/npcx/espi: Handle global reset events asserting eSPI_Reset#
In case there is a sudden power loss to PCH, then there are no eSPI VW messages sent from the PCH to EC indicating power state transition into S5. Instead, the eSPI compatibility spec defines such events as global reset events. For global reset events, eSPI_Reset# signal is asserted without SLP_SUS# being asserted. This acts as an indication to the EC that there was a global reset event. Add a callback chipset_handle_espi_reset_assert that takes any necessary action whenever eSPI_Reset# pin is asserted. On skylake, it would check if power button was being pressed and release the button. BUG=chrome-os-partner:62014 BRANCH=None TEST=Verified that apshutdown works as expected. Change-Id: I409afa0d00faca55ae3aa577743cedac58d4d877 Signed-off-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/438935 Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--chip/npcx/espi.c2
-rw-r--r--include/chipset.h6
-rw-r--r--power/skylake.c14
3 files changed, 22 insertions, 0 deletions
diff --git a/chip/npcx/espi.c b/chip/npcx/espi.c
index 41d61484a4..16cfe441e0 100644
--- a/chip/npcx/espi.c
+++ b/chip/npcx/espi.c
@@ -8,6 +8,7 @@
#include "registers.h"
#include "system.h"
#include "task.h"
+#include "chipset.h"
#include "console.h"
#include "uart.h"
#include "util.h"
@@ -542,6 +543,7 @@ void espi_interrupt(void)
} /* eSPI reset (from eSPI_rst pin) */
else if (IS_BIT_SET(status, NPCX_ESPISTS_ESPIRST)) {
CPRINTS("eSPI RST");
+ chipset_handle_espi_reset_assert();
espi_reset_recovery();
}
diff --git a/include/chipset.h b/include/chipset.h
index ac50df0cc1..3113643e17 100644
--- a/include/chipset.h
+++ b/include/chipset.h
@@ -82,6 +82,11 @@ void chipset_reset(int cold_reset);
*/
void power_interrupt(enum gpio_signal signal);
+/**
+ * Handle assert of eSPI_Reset# pin.
+ */
+void chipset_handle_espi_reset_assert(void);
+
#else /* !HAS_TASK_CHIPSET */
/*
* Allow other modules to compile if the chipset module is disabled. This is
@@ -98,6 +103,7 @@ static inline void chipset_throttle_cpu(int throttle) { }
static inline void chipset_force_shutdown(void) { }
static inline void chipset_reset(int cold_reset) { }
static inline void power_interrupt(enum gpio_signal signal) { }
+static inline void chipset_handle_espi_reset_assert(void) { }
#endif /* !HAS_TASK_CHIPSET */
diff --git a/power/skylake.c b/power/skylake.c
index 3afa94a684..02db88a79a 100644
--- a/power/skylake.c
+++ b/power/skylake.c
@@ -92,6 +92,20 @@ static void handle_slp_sus(enum power_state state)
chipset_set_pmic_slp_sus_l(gpio_get_level(GPIO_PCH_SLP_SUS_L));
}
+void chipset_handle_espi_reset_assert(void)
+{
+ /*
+ * If eSPI_Reset# pin is asserted without SLP_SUS# being asserted, then
+ * it means that there is an unexpected power loss (global reset
+ * event). In this case, check if shutdown was being forced by pressing
+ * power button. If yes, release power button.
+ */
+ if (power_has_signals(IN_PCH_SLP_SUS_DEASSERTED) && forcing_shutdown) {
+ power_button_pch_release();
+ forcing_shutdown = 0;
+ }
+}
+
enum power_state power_handle_state(enum power_state state)
{
enum power_state new_state;