diff options
author | Timur Tabi <timur@freescale.com> | 2011-07-08 07:12:42 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-09-19 19:19:42 -0400 |
commit | 14b9247019432fc25e606b78262eb16a4a33b8ed (patch) | |
tree | 505302eb318e3e03863ddeb528dca5f923bce002 /arch/powerpc/sysdev/mpic.c | |
parent | 41151e77a4d96ea138cede6d84c955aa4769ce74 (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.c | 24 |
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 | ||