summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2022-01-26 13:08:43 -0800
committerCommit Bot <commit-bot@chromium.org>2022-01-27 19:30:58 +0000
commit558c097b5949aadb1ff0eee0703dd846fbb011d7 (patch)
tree7f26456428a24073a8d093e9b648070185835dfe /power
parent00cb34b31d97ed44f2f8db97511abc7fe3c158a7 (diff)
downloadchrome-ec-558c097b5949aadb1ff0eee0703dd846fbb011d7.tar.gz
qcom: Move the execution of warm reset to CHIPSET context
In CrOS EC, the `apreset` command is executed in the CONSOLE context. But in Zephyr, the command is executed in the lowest priority task context. This low priority task is easily preempted and makes the power signal missing. This miss is wrongly treated as the PMIC not respond correctly and trigger a cold reset sequence: S0 -> S5 -> S0. This CL moves the execution to the CHIPSET task context. It is now independent from the console runtime. BRANCH=None BUG=b:215252361 TEST=Call the `apreset` command, just a warm reset triggered. Change-Id: I2be65db46b453421c2a04d10a75c01dbf16f1f89 Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3418118 Reviewed-by: Alexandru Stan <amstan@chromium.org>
Diffstat (limited to 'power')
-rw-r--r--power/qcom.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/power/qcom.c b/power/qcom.c
index 1a0bb49ec8..0ce1468577 100644
--- a/power/qcom.c
+++ b/power/qcom.c
@@ -169,6 +169,7 @@ enum power_request_t {
POWER_REQ_OFF,
POWER_REQ_ON,
POWER_REQ_COLD_RESET,
+ POWER_REQ_WARM_RESET,
POWER_REQ_COUNT,
};
@@ -250,6 +251,11 @@ void chipset_ap_rst_interrupt(enum gpio_signal signal)
power_signal_interrupt(signal);
}
+#ifdef CONFIG_CHIPSET_SC7180
+
+/* 1 if AP_RST_L and PS_HOLD is overdriven by EC */
+static char ap_rst_overdriven;
+
/* Issue a request to initiate a reset sequence */
static void request_cold_reset(void)
{
@@ -257,11 +263,6 @@ static void request_cold_reset(void)
task_wake(TASK_ID_CHIPSET);
}
-#ifdef CONFIG_CHIPSET_SC7180
-
-/* 1 if AP_RST_L and PS_HOLD is overdriven by EC */
-static char ap_rst_overdriven;
-
void chipset_warm_reset_interrupt(enum gpio_signal signal)
{
/*
@@ -848,18 +849,32 @@ static int warm_reset_seq(void)
return EC_SUCCESS;
}
-void chipset_reset(enum chipset_shutdown_reason reason)
+/**
+ * Check for some event triggering the warm reset.
+ *
+ * The only event is a request by the console command `apreset`.
+ */
+static void check_for_warm_reset_event(void)
{
int rv;
+ if (power_request == POWER_REQ_WARM_RESET) {
+ power_request = POWER_REQ_NONE;
+ rv = warm_reset_seq();
+ if (rv != EC_SUCCESS) {
+ CPRINTS("AP refuses to warm reset. Cold resetting.");
+ power_request = POWER_REQ_COLD_RESET;
+ }
+ }
+}
+
+void chipset_reset(enum chipset_shutdown_reason reason)
+{
CPRINTS("%s(%d)", __func__, reason);
report_ap_reset(reason);
- rv = warm_reset_seq();
- if (rv != EC_SUCCESS) {
- CPRINTS("AP refuses to warm reset. Cold resetting.");
- request_cold_reset();
- }
+ power_request = POWER_REQ_WARM_RESET;
+ task_wake(TASK_ID_CHIPSET);
}
/*
@@ -1070,6 +1085,8 @@ enum power_state power_handle_state(enum power_state state)
return POWER_S0;
case POWER_S0:
+ check_for_warm_reset_event();
+
shutdown_from_on = check_for_power_off_event();
if (shutdown_from_on) {
return POWER_S0S3;