diff options
author | Yilun Lin <yllin@google.com> | 2019-07-11 16:13:50 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-07-17 11:11:37 +0000 |
commit | 03ca813082a84001ce5e78c81da841a60c234975 (patch) | |
tree | 0da8aaf64190e5f357a504f9c2fd534e82cc5d8e | |
parent | 1445108e8e2e34383a2df5efd30157526a905577 (diff) | |
download | chrome-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.c | 21 |
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); |