summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzung-Bi Shih <tzungbi@chromium.org>2020-08-25 10:26:43 +0800
committerCommit Bot <commit-bot@chromium.org>2020-08-26 23:16:13 +0000
commitb7790f6c6b084a3872a2b2106d2a3228c3d32d3c (patch)
treeabb0b69ba1c2eefa2cb25a10f8ac4c074c1e13d9
parente867930ac6fc4d2f8ac6607bc78bb14469a99c94 (diff)
downloadchrome-ec-b7790f6c6b084a3872a2b2106d2a3228c3d32d3c.tar.gz
chip/mt8192_scp: do not switch INTC_IRQ_EN in runtime
MT8192 SCP's interrupt handling is a long path. +----------+ +----------+ +----------+ | INTC | ---> | GVIC | ---> | RV33 | +----------+ +----------+ +----------+ ^ ^ ^ ^ INTC_IRQ_EN VIC_EN MIMASK mie When turning off INTC_IRQ_EN, it is possible GVIC has already latched the interrupt. As a result, RV33 receives the spurious interrupt. MT8192 SCP has no effective way to clear the unwanted interrupt. Thus, do not switch INTC_IRQ_EN in runtime. Disable all interrupts (via mie) instead. BRANCH=none BUG=b:163682416 TEST=1. cat - <<EOF >test.sh echo stop >/sys/class/remoteproc/remoteproc0/state while :; do dmesg -C echo start >/sys/class/remoteproc/remoteproc0/state sleep 1 if dmesg | grep -q 'rpmsg send timeout'; then break fi echo stop >/sys/class/remoteproc/remoteproc0/state done echo stop >/sys/class/remoteproc/remoteproc0/state EOF 2. sh test.sh Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org> Change-Id: I494330f8d00744c305be7beb19ca6b7084512a72 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2373845 Reviewed-by: Ting Shen <phoenixshen@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2378953 Reviewed-by: Edward Hill <ecgh@chromium.org> Commit-Queue: Edward Hill <ecgh@chromium.org> Tested-by: Edward Hill <ecgh@chromium.org>
-rw-r--r--chip/mt8192_scp/ipi.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/chip/mt8192_scp/ipi.c b/chip/mt8192_scp/ipi.c
index e8aadb4165..2f67f7fa14 100644
--- a/chip/mt8192_scp/ipi.c
+++ b/chip/mt8192_scp/ipi.c
@@ -26,12 +26,14 @@ static struct ipc_shared_obj *const ipi_recv_buf =
(struct ipc_shared_obj *)(CONFIG_IPC_SHARED_OBJ_ADDR +
sizeof(struct ipc_shared_obj));
-static uint32_t disable_irq_count;
+static uint32_t disable_irq_count, saved_int_mask;
void ipi_disable_irq(void)
{
- if (atomic_inc(&disable_irq_count, 1) == 0)
- task_disable_irq(SCP_IRQ_GIPC_IN0);
+ if (atomic_inc(&disable_irq_count, 1) == 0) {
+ saved_int_mask = get_int_mask();
+ interrupt_disable();
+ }
}
void ipi_enable_irq(void)
@@ -39,7 +41,7 @@ void ipi_enable_irq(void)
if (atomic_dec(&disable_irq_count, 1) == 1) {
int pending = SCP_GIPC_IN_SET;
- task_enable_irq(SCP_IRQ_GIPC_IN0);
+ set_int_mask(saved_int_mask);
if (init_done && pending)
task_trigger_irq(SCP_IRQ_GIPC_IN0);