summaryrefslogtreecommitdiff
path: root/power/sdm845.c
diff options
context:
space:
mode:
Diffstat (limited to 'power/sdm845.c')
-rw-r--r--power/sdm845.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/power/sdm845.c b/power/sdm845.c
index fb3eb40efc..ded32ee64b 100644
--- a/power/sdm845.c
+++ b/power/sdm845.c
@@ -73,6 +73,14 @@ static char power_button_was_pressed;
/* 1 if lid-open event has been detected */
static char lid_opened;
+/*
+ * 1 if power state is controlled by special functions, like a console command
+ * or an interrupt handler, for bypassing POWER_GOOD lost trigger. It is
+ * because these functions control the PMIC and AP power signals directly and
+ * don't want to get preempted by the chipset state machine.
+ */
+static uint8_t bypass_power_lost_trigger;
+
/* Time where we will power off, if power button still held down */
static timestamp_t power_off_deadline;
@@ -116,6 +124,19 @@ enum power_on_event_t {
POWER_ON_EVENT_COUNT,
};
+/* AP-requested reset GPIO interrupt handlers */
+static void chipset_reset_request_handler(void)
+{
+ CPRINTS("AP wants reset");
+ chipset_reset();
+}
+DECLARE_DEFERRED(chipset_reset_request_handler);
+
+void chipset_reset_request_interrupt(enum gpio_signal signal)
+{
+ hook_call_deferred(&chipset_reset_request_handler_data, 0);
+}
+
static void sdm845_lid_event(void)
{
/* Power task only cares about lid-open events */
@@ -257,6 +278,9 @@ enum power_state power_chipset_init(void)
int init_power_state;
uint32_t reset_flags = system_get_reset_flags();
+ /* Enable reboot control input from AP */
+ gpio_enable_interrupt(GPIO_AP_RST_REQ);
+
/*
* Force the AP shutdown unless we are doing SYSJUMP. Otherwise,
* the AP could stay in strange state.
@@ -444,7 +468,7 @@ static int check_for_power_off_event(void)
power_button_was_pressed = pressed;
/* POWER_GOOD released by AP : shutdown immediately */
- if (!power_has_signals(IN_POWER_GOOD)) {
+ if (!power_has_signals(IN_POWER_GOOD) && !bypass_power_lost_trigger) {
if (power_button_was_pressed)
timer_cancel(TASK_ID_CHIPSET);
@@ -474,7 +498,9 @@ void chipset_reset(void)
* reset pin and zero-latency. We do cold reset instead.
*/
CPRINTS("EC triggered cold reboot");
+ bypass_power_lost_trigger = 1;
power_off();
+ bypass_power_lost_trigger = 0;
/* Issue a request to initiate a power-on sequence */
power_request = POWER_REQ_ON;