summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYilun Lin <yllin@google.com>2019-07-11 16:13:50 +0800
committerCommit Bot <commit-bot@chromium.org>2019-07-17 11:11:37 +0000
commit03ca813082a84001ce5e78c81da841a60c234975 (patch)
tree0da8aaf64190e5f357a504f9c2fd534e82cc5d8e
parent1445108e8e2e34383a2df5efd30157526a905577 (diff)
downloadchrome-ec-03ca813082a84001ce5e78c81da841a60c234975.tar.gz
mt_scp: Trigger IRQ if has pending IPC when re-enable SCP_IRQ_IPC0.
Prevent a starved waiting IPC. IPC may be requested while SCP_IRQ_IPC0 is disabled, and this may result in AP dead waiting for a reply from SCP. This CL forces triggering the SCP_IRQ_IPC0 if seeing a pending IPC when re-enable the SCP_IRQ_IPC0. TEST=run factory front_camera_test for over 1 hr and see AP doesn't complains HC not respsonsed. BUG=b:136809224, b:136616282 BRANCH=None Change-Id: Ic36da774994f6c571c3b79fd6717562f8866b7df Signed-off-by: Yilun Lin <yllin@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1697884 Reviewed-by: Nicolas Boichat <drinkcat@chromium.org> Commit-Queue: Yilun Lin <yllin@chromium.org> Tested-by: Yilun Lin <yllin@chromium.org>
-rw-r--r--chip/mt_scp/ipi.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/chip/mt_scp/ipi.c b/chip/mt_scp/ipi.c
index 1afdf108ea..8819586a2f 100644
--- a/chip/mt_scp/ipi.c
+++ b/chip/mt_scp/ipi.c
@@ -105,9 +105,21 @@ void ipi_enable_irq(int irq)
mutex_lock(&ipc0_lock);
- if ((++ipc0_enabled_count) == 1)
+ if ((++ipc0_enabled_count) == 1) {
+ int pending_ipc = SCP_GIPC_IN & SCP_GPIC_IN_CLEAR_ALL;
+
task_enable_irq(irq);
+ if (pending_ipc)
+ /*
+ * IPC may be triggered while SCP_IRQ_IPC0 was disabled.
+ * AP will still updates SCP_GIPC_IN.
+ * Trigger the IRQ handler if it has a
+ * pending IPC.
+ */
+ task_trigger_irq(irq);
+ }
+
mutex_unlock(&ipc0_lock);
}
@@ -144,6 +156,7 @@ int ipi_send(int32_t id, const void *buf, uint32_t len, int wait)
mutex_unlock(&ipi_lock);
ipi_enable_irq(SCP_IRQ_IPC0);
+ CPRINTS("Err: IPI Busy, %d", id);
return EC_ERROR_BUSY;
}
@@ -329,9 +342,11 @@ DECLARE_HOOK(HOOK_INIT, ipi_init, HOOK_PRIO_DEFAULT);
void ipc_handler(void)
{
/* TODO(b/117917141): We only support IPC_ID(0) for now. */
- if (SCP_GIPC_IN & SCP_GIPC_IN_CLEAR_IPCN(0))
+ if (SCP_GIPC_IN & SCP_GIPC_IN_CLEAR_IPCN(0)) {
ipi_handler();
+ SCP_GIPC_IN &= SCP_GIPC_IN_CLEAR_IPCN(0);
+ }
- SCP_GIPC_IN = SCP_GPIC_IN_CLEAR_ALL;
+ SCP_GIPC_IN &= (SCP_GPIC_IN_CLEAR_ALL & ~SCP_GIPC_IN_CLEAR_IPCN(0));
}
DECLARE_IRQ(SCP_IRQ_IPC0, ipc_handler, 4);