diff options
-rw-r--r-- | arch/arm/common/bL_switcher.c | 14 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic.c | 21 | ||||
-rw-r--r-- | include/linux/irqchip/arm-gic.h | 1 |
3 files changed, 35 insertions, 1 deletions
diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c index 50e95d894e35..1c2e5bcfb1f7 100644 --- a/arch/arm/common/bL_switcher.c +++ b/arch/arm/common/bL_switcher.c | |||
@@ -110,6 +110,8 @@ static int bL_switchpoint(unsigned long _arg) | |||
110 | * Generic switcher interface | 110 | * Generic switcher interface |
111 | */ | 111 | */ |
112 | 112 | ||
113 | static unsigned int bL_gic_id[MAX_CPUS_PER_CLUSTER][MAX_NR_CLUSTERS]; | ||
114 | |||
113 | /* | 115 | /* |
114 | * bL_switch_to - Switch to a specific cluster for the current CPU | 116 | * bL_switch_to - Switch to a specific cluster for the current CPU |
115 | * @new_cluster_id: the ID of the cluster to switch to. | 117 | * @new_cluster_id: the ID of the cluster to switch to. |
@@ -159,7 +161,7 @@ static int bL_switch_to(unsigned int new_cluster_id) | |||
159 | this_cpu = smp_processor_id(); | 161 | this_cpu = smp_processor_id(); |
160 | 162 | ||
161 | /* redirect GIC's SGIs to our counterpart */ | 163 | /* redirect GIC's SGIs to our counterpart */ |
162 | gic_migrate_target(cpuid + ib_cluster*4); | 164 | gic_migrate_target(bL_gic_id[cpuid][ib_cluster]); |
163 | 165 | ||
164 | /* | 166 | /* |
165 | * Raise a SGI on the inbound CPU to make sure it doesn't stall | 167 | * Raise a SGI on the inbound CPU to make sure it doesn't stall |
@@ -332,6 +334,16 @@ static int __init bL_switcher_halve_cpus(void) | |||
332 | cluster = (cpu_logical_map(i) >> 8) & 0xff; | 334 | cluster = (cpu_logical_map(i) >> 8) & 0xff; |
333 | 335 | ||
334 | if (cpumask_test_cpu(cpu, &common_mask)) { | 336 | if (cpumask_test_cpu(cpu, &common_mask)) { |
337 | /* Let's take note of the GIC ID for this CPU */ | ||
338 | int gic_id = gic_get_cpu_id(i); | ||
339 | if (gic_id < 0) { | ||
340 | pr_err("%s: bad GIC ID for CPU %d\n", __func__, i); | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | bL_gic_id[cpu][cluster] = gic_id; | ||
344 | pr_info("GIC ID for CPU %u cluster %u is %u\n", | ||
345 | cpu, cluster, gic_id); | ||
346 | |||
335 | /* | 347 | /* |
336 | * We keep only those logical CPUs which number | 348 | * We keep only those logical CPUs which number |
337 | * is equal to their physical CPU number. This is | 349 | * is equal to their physical CPU number. This is |
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 268874ac75e6..3862cb54c714 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -668,6 +668,27 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | |||
668 | 668 | ||
669 | #ifdef CONFIG_BL_SWITCHER | 669 | #ifdef CONFIG_BL_SWITCHER |
670 | /* | 670 | /* |
671 | * gic_get_cpu_id - get the CPU interface ID for the specified CPU | ||
672 | * | ||
673 | * @cpu: the logical CPU number to get the GIC ID for. | ||
674 | * | ||
675 | * Return the CPU interface ID for the given logical CPU number, | ||
676 | * or -1 if the CPU number is too large or the interface ID is | ||
677 | * unknown (more than one bit set). | ||
678 | */ | ||
679 | int gic_get_cpu_id(unsigned int cpu) | ||
680 | { | ||
681 | unsigned int cpu_bit; | ||
682 | |||
683 | if (cpu >= NR_GIC_CPU_IF) | ||
684 | return -1; | ||
685 | cpu_bit = gic_cpu_map[cpu]; | ||
686 | if (cpu_bit & (cpu_bit - 1)) | ||
687 | return -1; | ||
688 | return __ffs(cpu_bit); | ||
689 | } | ||
690 | |||
691 | /* | ||
671 | * gic_migrate_target - migrate IRQs to another CPU interface | 692 | * gic_migrate_target - migrate IRQs to another CPU interface |
672 | * | 693 | * |
673 | * @new_cpu_id: the CPU target ID to migrate IRQs to | 694 | * @new_cpu_id: the CPU target ID to migrate IRQs to |
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 40bfcac95940..2d7d47e8dfaf 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h | |||
@@ -75,6 +75,7 @@ static inline void gic_init(unsigned int nr, int start, | |||
75 | gic_init_bases(nr, start, dist, cpu, 0, NULL); | 75 | gic_init_bases(nr, start, dist, cpu, 0, NULL); |
76 | } | 76 | } |
77 | 77 | ||
78 | int gic_get_cpu_id(unsigned int cpu); | ||
78 | void gic_migrate_target(unsigned int new_cpu_id); | 79 | void gic_migrate_target(unsigned int new_cpu_id); |
79 | 80 | ||
80 | #endif /* __ASSEMBLY */ | 81 | #endif /* __ASSEMBLY */ |