summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi3
-rw-r--r--drivers/irqchip/irq-gic-v3.c18
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;