summaryrefslogtreecommitdiff
path: root/arch/arm/common
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-10-11 22:59:38 -0700
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-21 12:06:22 +0530
commitc120cd23315024dd1edd2f268a6a3c73826f826d (patch)
treeaab64e84d0ab183c58d6b5c87b75cb4924a31046 /arch/arm/common
parentbad4cd4f610e7ace9fa735919398144faa164bb8 (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>
Diffstat (limited to 'arch/arm/common')
-rw-r--r--arch/arm/common/Kconfig9
-rw-r--r--arch/arm/common/gic.c13
2 files changed, 21 insertions, 1 deletions
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 638256600ffe..23b2a6a98c27 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -89,3 +89,12 @@ config FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE
help
If enabled, this puts the fiq debugger into console mode by default.
Otherwise, the fiq debugger will start out in debug mode.
+
+config GIC_SET_MULTIPLE_CPUS
+ bool "Use affinity hint to allow multiple CPUs for IRQ"
+ depends on ARM_GIC && SMP
+ default n
+ help
+ IRQ affinity is always set by gic to the 1st cpu in the requested
+ mask. If this option is enabled, affinity is also set to all cpus
+ present in affinity_hint and requested masks.
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 60e6175dc11d..05cd423c5750 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -176,6 +176,9 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
unsigned int shift = (d->irq % 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 >= 8 || cpu >= nr_cpu_ids)
return -EINVAL;
@@ -185,7 +188,15 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
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);
spin_unlock(&irq_controller_lock);
return IRQ_SET_MASK_OK;