summaryrefslogtreecommitdiff
path: root/drivers/irqchip/irq-gic-v3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/irqchip/irq-gic-v3.c')
-rw-r--r--drivers/irqchip/irq-gic-v3.c21
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;