diff options
-rw-r--r-- | arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 18 |
2 files changed, 19 insertions, 2 deletions
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi index 272b492b2aa7..52fdd82b5b38 100644 --- a/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi @@ -70,7 +70,8 @@ gic: interrupt-controller@38800000 { compatible = "arm,gic-v3"; reg = <0x0 0x38800000 0 0x10000>, /* GIC Dist */ - <0x0 0x38880000 0 0xC0000>; /* GICR (RD_base + SGI_base) */ + <0x0 0x38880000 0 0xC0000>, /* GICR (RD_base + SGI_base) */ + <0x0 0x30340000 0x0 0x10000>; /* IOMUXC_GPR */ #interrupt-cells = <3>; interrupt-controller; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 3d7374655587..d4093cd24a1e 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -62,6 +62,8 @@ struct gic_chip_data { static struct gic_chip_data gic_data __read_mostly; static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE; +static void __iomem *iomuxc_gpr_base; + static struct gic_kvm_info gic_v3_kvm_info; #define gic_data_rdist() (this_cpu_ptr(gic_data.rdists.rdist)) @@ -652,6 +654,7 @@ static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq) static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) { int cpu; + u32 val; if (WARN_ON(irq >= 16)) return; @@ -668,8 +671,18 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) tlist = gic_compute_target_list(&cpu, mask, cluster_id); gic_send_sgi(cluster_id, tlist, irq); - } + if (iomuxc_gpr_base) { + /* pending the IRQ32 to wakeup the core */ + val = readl_relaxed(iomuxc_gpr_base + 0x4); + val |= (1 << 12); + writel_relaxed(val, iomuxc_gpr_base + 0x4); + /* delay for a while to make sure cores wakeup done */ + udelay(50); + val &= ~(1 << 12); + writel_relaxed(val, iomuxc_gpr_base + 0x4); + } + } /* Force the above writes to ICC_SGI1R_EL1 to be executed */ isb(); } @@ -1222,6 +1235,9 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare rdist_regs[i].phys_base = res.start; } + /* sw workaround for IPI can't wakeup CORE ERRATA(ERR011171) on i.MX8MQ */ + iomuxc_gpr_base = of_iomap(node, 2); + if (of_property_read_u64(node, "redistributor-stride", &redist_stride)) redist_stride = 0; |