ARM: tegra: power: Restore IRQ multiple CPU affinity
Alex Frid [Sat, 10 Dec 2011 03:21:36 +0000 (19:21 -0800)]
Restore IRQ affinity to multiple CPUs after LP=>G CPU mode switch.

Change-Id: Id7c263f2a11535669d1e9988f4e15b240a7fde38
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/69329
Reviewed-by: Lokesh Pathak <lpathak@nvidia.com>
Tested-by: Lokesh Pathak <lpathak@nvidia.com>

Rebase-Id: R669e1583e757f6dd6c23205b9798ca44a50b7257

arch/arm/mach-tegra/pm-t3.c

index 61fbc6a..cd3135f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/clk.h>
 #include <linux/cpu_pm.h>
 #include <linux/delay.h>
+#include <linux/irq.h>
 
 #include <mach/gpio.h>
 #include <mach/irqs.h>
@@ -261,8 +262,25 @@ static void cluster_switch_epilog_gic(void)
        max_irq = readl(gic_base + GIC_DIST_CTR) & 0x1f;
        max_irq = (max_irq + 1) * 32;
 
-       for (i = 32; i < max_irq; i += 4)
-               writel(0x01010101, gic_base + GIC_DIST_TARGET + i * 4 / 4);
+       for (i = 32; i < max_irq; i += 4) {
+               u32 val = 0x01010101;
+#ifdef CONFIG_GIC_SET_MULTIPLE_CPUS
+               unsigned int irq;
+               for (irq = i; irq < (i + 4); irq++) {
+                       struct cpumask mask;
+                       struct irq_desc *desc = irq_to_desc(irq);
+
+                       if (desc && desc->affinity_hint &&
+                           desc->irq_data.affinity) {
+                               if (cpumask_and(&mask, desc->affinity_hint,
+                                               desc->irq_data.affinity))
+                                       val |= (*cpumask_bits(&mask) & 0xff) <<
+                                               ((irq & 3) * 8);
+                       }
+               }
+#endif
+               writel(val, gic_base + GIC_DIST_TARGET + i * 4 / 4);
+       }
 }
 
 void tegra_cluster_switch_epilog(unsigned int flags)