diff options
author | Tzung-Bi Shih <tzungbi@chromium.org> | 2020-08-25 10:26:43 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-08-26 23:16:13 +0000 |
commit | b7790f6c6b084a3872a2b2106d2a3228c3d32d3c (patch) | |
tree | abb0b69ba1c2eefa2cb25a10f8ac4c074c1e13d9 | |
parent | e867930ac6fc4d2f8ac6607bc78bb14469a99c94 (diff) | |
download | chrome-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.c | 10 |
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); |