diff options
author | Alex Frid <afrid@nvidia.com> | 2011-10-11 22:59:38 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 01:32:24 -0700 |
commit | 1d5bee1f55e25172cff6f8ccb7df414973fb9de2 (patch) | |
tree | ad480430e2d41ab48e21608e7142394f9f39cc84 /drivers/irqchip | |
parent | 683a4978fa82caa250fe47bd73809c569756e666 (diff) |
ARM: gic: Use affinity hint to set multiple CPUs for IRQ
GIC IRQ affinity is currently set to one CPU only - the 1st cpu in
the requested mask. This commit adds option to set IRQ affinity to
all cpus present in affinity_hint and requested masks. The option is
enabled by default on Tegra architecture starting with Tegra3.
(cherry picked from commit 09f7ef4f28a6e18188649c40848252bc18a6646c)
Change-Id: I0d655f1d39170382f3372294172ed6d02dc0ad49
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/69328
Reviewed-by: Lokesh Pathak <lpathak@nvidia.com>
Tested-by: Lokesh Pathak <lpathak@nvidia.com>
Rebase-Id: R31f7a5ed91995a83d55d051a5926dc47f33b87ea
Diffstat (limited to 'drivers/irqchip')
-rw-r--r-- | drivers/irqchip/irq-gic.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 19ceaa60e0f4..b8f60eee236d 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -249,6 +249,9 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, unsigned int shift = (gic_irq(d) % 4) * 8; unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); u32 val, mask, bit; +#ifdef CONFIG_GIC_SET_MULTIPLE_CPUS + struct irq_desc *desc = irq_to_desc(d->irq); +#endif if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) return -EINVAL; @@ -258,7 +261,15 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, raw_spin_lock(&irq_controller_lock); val = readl_relaxed(reg) & ~mask; - writel_relaxed(val | bit, reg); + val |= bit; +#ifdef CONFIG_GIC_SET_MULTIPLE_CPUS + if (desc && desc->affinity_hint) { + struct cpumask mask_hint; + if (cpumask_and(&mask_hint, desc->affinity_hint, mask_val)) + val |= (*cpumask_bits(&mask_hint) << shift) & mask; + } +#endif + writel_relaxed(val, reg); raw_spin_unlock(&irq_controller_lock); return IRQ_SET_MASK_OK; |