From 03ca813082a84001ce5e78c81da841a60c234975 Mon Sep 17 00:00:00 2001 From: Yilun Lin Date: Thu, 11 Jul 2019 16:13:50 +0800 Subject: 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 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1697884 Reviewed-by: Nicolas Boichat Commit-Queue: Yilun Lin Tested-by: Yilun Lin --- chip/mt_scp/ipi.c | 21 ++++++++++++++++++--- 1 file 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); -- cgit v1.2.1