summaryrefslogtreecommitdiff
path: root/power/apollolake.c
diff options
context:
space:
mode:
Diffstat (limited to 'power/apollolake.c')
-rw-r--r--power/apollolake.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/power/apollolake.c b/power/apollolake.c
index 69d253c8fd..c1fcbe8e17 100644
--- a/power/apollolake.c
+++ b/power/apollolake.c
@@ -9,23 +9,42 @@
#include "console.h"
#include "gpio.h"
#include "intel_x86.h"
+#include "task.h"
#include "timer.h"
/* Console output macros */
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
+/*
+ * force_shutdown is used to maintain chipset shutdown request. This request
+ * needs to be handled from within the chipset task.
+ */
+static int force_shutdown;
+
__attribute__((weak)) void chipset_do_shutdown(void)
{
/* Need to implement board specific shutdown */
}
-void chipset_force_shutdown(void)
+static void internal_chipset_shutdown(void)
{
CPRINTS("%s()", __func__);
+ force_shutdown = 0;
chipset_do_shutdown();
}
+void chipset_force_shutdown(void)
+{
+ /*
+ * 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
+ * misses out.
+ */
+ force_shutdown = 1;
+ task_wake(TASK_ID_CHIPSET);
+}
+
enum power_state chipset_force_g3(void)
{
chipset_force_shutdown();
@@ -64,13 +83,17 @@ enum power_state power_handle_state(enum power_state state)
if (state == POWER_S5 && !power_has_signals(IN_PGOOD_ALL_CORE)) {
/* Required rail went away */
- chipset_force_shutdown();
+ internal_chipset_shutdown();
new_state = POWER_S5G3;
goto rsmrst_handle;
}
+ /* If force shutdown is requested, perform that. */
+ if (force_shutdown)
+ internal_chipset_shutdown();
+
new_state = common_intel_x86_power_handle_state(state);
rsmrst_handle: