summaryrefslogtreecommitdiff
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-10-11 22:59:38 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 01:32:24 -0700
commit1d5bee1f55e25172cff6f8ccb7df414973fb9de2 (patch)
treead480430e2d41ab48e21608e7142394f9f39cc84 /drivers/irqchip
parent683a4978fa82caa250fe47bd73809c569756e666 (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.c13
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;