diff options
Diffstat (limited to 'drivers/irqchip/irq-gic-v3.c')
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 2ab6060031a4..eac9a76fdccb 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)) @@ -607,6 +609,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; @@ -623,8 +626,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(10); + val &= ~(1 << 12); + writel_relaxed(val, iomuxc_gpr_base + 0x4); + } + } /* Force the above writes to ICC_SGI1R_EL1 to be executed */ isb(); } @@ -1164,6 +1177,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare rdist_regs[i].phys_base = res.start; } + if (of_machine_is_compatible("fsl,imx8mq")) { + /* 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; |