aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorMatthias Schiffer2022-09-26 10:31:08 +0200
committerStefano Babic2022-11-07 22:45:04 +0100
commit975f4117d5592312acd14d715fd7498361a77b57 (patch)
tree12d400ec35c7a9c50dee2d4c20dba55df7a5b5f4 /arch/arm/mach-imx
parenta887f2ac3e6c2479476ff0ef82c1d2e23178b6f9 (diff)
ARM: mx7: psci: fix suspend/resume e10133 workaround
The e10133 workaround was broken in two places: - The code intended to temporarily mask all interrupts in GPC_IMRx_CORE0. While the old register values were saved, the actual masking was missing. - imx_udelay() expects the system counter to run at its base frequency, but the system counter is switched to a lower frequency earlier in psci_system_suspend(), leading to a much longer delay than intended. Replace the call with an equivalent loop (linux-imx 5.15 does the same) This fixes the SoC hanging forever when there was already a wakeup IRQ pending while suspending. Fixes: 57b620255e ("imx: mx7: add system suspend/resume support") Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/mx7/psci-mx7.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/arm/mach-imx/mx7/psci-mx7.c b/arch/arm/mach-imx/mx7/psci-mx7.c
index f32945ea371..699a2569cb7 100644
--- a/arch/arm/mach-imx/mx7/psci-mx7.c
+++ b/arch/arm/mach-imx/mx7/psci-mx7.c
@@ -643,8 +643,10 @@ __secure void psci_system_suspend(u32 __always_unused function_id,
/* disable GIC distributor */
writel(0, GIC400_ARB_BASE_ADDR + GIC_DIST_OFFSET);
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++) {
gpc_mask[i] = readl(GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4);
+ writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4);
+ }
/*
* enable the RBC bypass counter here
@@ -668,7 +670,7 @@ __secure void psci_system_suspend(u32 __always_unused function_id,
writel(gpc_mask[i], GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4);
/*
- * now delay for a short while (3usec)
+ * now delay for a short while (~3usec)
* ARM is at 1GHz at this point
* so a short loop should be enough.
* this delay is required to ensure that
@@ -677,7 +679,8 @@ __secure void psci_system_suspend(u32 __always_unused function_id,
* or in case an interrupt arrives just
* as ARM is about to assert DSM_request.
*/
- imx_udelay(3);
+ for (i = 0; i < 2000; i++)
+ asm volatile("");
/* save resume entry and sp in CPU0 GPR registers */
asm volatile("mov %0, sp" : "=r" (val));