diff options
author | Alex Frid <afrid@nvidia.com> | 2011-10-11 22:59:38 -0700 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2011-12-21 12:06:22 +0530 |
commit | c120cd23315024dd1edd2f268a6a3c73826f826d (patch) | |
tree | aab64e84d0ab183c58d6b5c87b75cb4924a31046 /arch/arm/common | |
parent | bad4cd4f610e7ace9fa735919398144faa164bb8 (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/Kconfig | 9 | ||||
-rw-r--r-- | arch/arm/common/gic.c | 13 |
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; |