From a34e259cc0a4e86ccb993c947991d2823d81eb14 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Mon, 27 Apr 2015 19:05:08 +0800 Subject: MLK-10760 ARM: imx: need to make sure GPR irq is pending in run mode Due to hardware design requirement, GPR interrupt need to be pending in RUN mode to avoid entering DSM mode by mistake, only when entering low power mode, we can mask this interrupt. This interrupt is only unmasked in GPC, ARM is NOT aware of it, so it will NOT impact any system function in kernel. Signed-off-by: Anson Huang --- arch/arm/mach-imx/gpcv2.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-imx/gpcv2.c b/arch/arm/mach-imx/gpcv2.c index e11c03b4d294..c6c4e60ef213 100644 --- a/arch/arm/mach-imx/gpcv2.c +++ b/arch/arm/mach-imx/gpcv2.c @@ -171,13 +171,28 @@ void imx_gpcv2_set_lpm_mode(u32 cpu, enum mxc_cpu_pwr_mode mode) val2 &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN | BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY); + /* + * GPC: When improper low-power sequence is used, + * the SoC enters low power mode before the ARM core executes WFI. + * + * Software workaround: + * 1) Software should trigger IRQ #32 (IOMUX) to be always pending + * by setting IOMUX_GPR1_IRQ. + * 2) Software should then unmask IRQ #32 in GPC before setting GPC + * Low-Power mode. + * 3) Software should mask IRQ #32 right after GPC Low-Power mode + * is set. + */ + iomuxc_irq_desc = irq_to_desc(32); switch (mode) { case WAIT_CLOCKED: + imx_gpcv2_irq_unmask(&iomuxc_irq_desc->irq_data); break; case WAIT_UNCLOCKED: val1 |= A7_LPM_WAIT << BP_LPCR_A7_BSC_LPM0; val1 &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM; + imx_gpcv2_irq_mask(&iomuxc_irq_desc->irq_data); break; case STOP_POWER_OFF: val1 |= A7_LPM_STOP << BP_LPCR_A7_BSC_LPM0; @@ -187,27 +202,13 @@ void imx_gpcv2_set_lpm_mode(u32 cpu, enum mxc_cpu_pwr_mode mode) val2 |= BM_SLPCR_SBYOS; val2 |= BM_SLPCR_VSTBY; val2 |= BM_SLPCR_BYPASS_PMIC_READY; + imx_gpcv2_irq_mask(&iomuxc_irq_desc->irq_data); break; default: return; } - /* - * GPC: When improper low-power sequence is used, - * the SoC enters low power mode before the ARM core executes WFI. - * - * Software workaround: - * 1) Software should trigger IRQ #32 (IOMUX) to be always pending - * by setting IOMUX_GPR1_IRQ. - * 2) Software should then unmask IRQ #32 in GPC before setting GPC - * Low-Power mode. - * 3) Software should mask IRQ #32 right after GPC Low-Power mode - * is set. - */ - iomuxc_irq_desc = irq_to_desc(32); - imx_gpcv2_irq_unmask(&iomuxc_irq_desc->irq_data); writel_relaxed(val1, gpc_base + GPC_LPCR_A7_BSC); writel_relaxed(val2, gpc_base + GPC_SLPCR); - imx_gpcv2_irq_mask(&iomuxc_irq_desc->irq_data); spin_unlock_irqrestore(&gpcv2_lock, flags); } @@ -506,6 +507,12 @@ void __init imx_gpcv2_init(void) writel_relaxed(~0, gpc_base + GPC_IMR1_CORE0 + i * 4); writel_relaxed(~0, gpc_base + GPC_IMR1_CORE1 + i * 4); } + /* + * Due to hardware design requirement, need to make sure GPR + * interrupt(#32) is unmasked during RUN mode to avoid entering + * DSM by mistake. + */ + writel_relaxed(~0x1, gpc_base + GPC_IMR1_CORE0); /* Read supported wakeup source in M/F domain */ if (cpu_is_imx7d()) { -- cgit v1.2.3