aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/mpic.c
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2011-07-08 07:12:42 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-19 19:19:42 -0400
commit14b9247019432fc25e606b78262eb16a4a33b8ed (patch)
tree505302eb318e3e03863ddeb528dca5f923bce002 /arch/powerpc/sysdev/mpic.c
parent41151e77a4d96ea138cede6d84c955aa4769ce74 (diff)
powerpc/mpic: Add support for discontiguous cores
There is one place in the MPIC driver that assumes that the cores are numbered from 0 to n-1. However, this is not true if the CPUs are not numbered sequentially. This can happen on a eight-core SOC where cores two and three are removed in the device tree. So instead of blindly looping, we iterate over the discovered CPUs and use the SMP ID as the index. This means that we no longer ask the MPIC how many CPUs there are, so we also delete mpic->num_cpus. We also catch if the number of CPUs in the SOC exceeds the number that the MPIC supports. This should never happen, of course, but it's good to be sure. Signed-off-by: Timur Tabi <timur@freescale.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r--arch/powerpc/sysdev/mpic.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index d5d3ff3d757e..9678081dc4e2 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1285,13 +1285,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1285 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) 1285 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1286 | MPIC_GREG_GCONF_MCK); 1286 | MPIC_GREG_GCONF_MCK);
1287 1287
1288 /* Read feature register, calculate num CPUs and, for non-ISU 1288 /*
1289 * MPICs, num sources as well. On ISU MPICs, sources are counted 1289 * Read feature register. For non-ISU MPICs, num sources as well. On
1290 * as ISUs are added 1290 * ISU MPICs, sources are counted as ISUs are added
1291 */ 1291 */
1292 greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); 1292 greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
1293 mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK)
1294 >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
1295 if (isu_size == 0) { 1293 if (isu_size == 0) {
1296 if (flags & MPIC_BROKEN_FRR_NIRQS) 1294 if (flags & MPIC_BROKEN_FRR_NIRQS)
1297 mpic->num_sources = mpic->irq_count; 1295 mpic->num_sources = mpic->irq_count;
@@ -1301,10 +1299,18 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1301 >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; 1299 >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
1302 } 1300 }
1303 1301
1302 /*
1303 * The MPIC driver will crash if there are more cores than we
1304 * can initialize, so we may as well catch that problem here.
1305 */
1306 BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS);
1307
1304 /* Map the per-CPU registers */ 1308 /* Map the per-CPU registers */
1305 for (i = 0; i < mpic->num_cpus; i++) { 1309 for_each_possible_cpu(i) {
1306 mpic_map(mpic, node, paddr, &mpic->cpuregs[i], 1310 unsigned int cpu = get_hard_smp_processor_id(i);
1307 MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), 1311
1312 mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu],
1313 MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
1308 0x1000); 1314 0x1000);
1309 } 1315 }
1310 1316
@@ -1343,7 +1349,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1343 } 1349 }
1344 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," 1350 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
1345 " max %d CPUs\n", 1351 " max %d CPUs\n",
1346 name, vers, (unsigned long long)paddr, mpic->num_cpus); 1352 name, vers, (unsigned long long)paddr, num_possible_cpus());
1347 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", 1353 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
1348 mpic->isu_size, mpic->isu_shift, mpic->isu_mask); 1354 mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
1349 1355