aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/mpic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r--arch/powerpc/sysdev/mpic.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index d5d3ff3d757e..8c7e8528e7c4 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -800,8 +800,6 @@ static void mpic_end_ipi(struct irq_data *d)
800 * IPIs are marked IRQ_PER_CPU. This has the side effect of 800 * IPIs are marked IRQ_PER_CPU. This has the side effect of
801 * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from 801 * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
802 * applying to them. We EOI them late to avoid re-entering. 802 * applying to them. We EOI them late to avoid re-entering.
803 * We mark IPI's with IRQF_DISABLED as they must run with
804 * irqs disabled.
805 */ 803 */
806 mpic_eoi(mpic); 804 mpic_eoi(mpic);
807} 805}
@@ -1285,13 +1283,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1285 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) 1283 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1286 | MPIC_GREG_GCONF_MCK); 1284 | MPIC_GREG_GCONF_MCK);
1287 1285
1288 /* Read feature register, calculate num CPUs and, for non-ISU 1286 /*
1289 * MPICs, num sources as well. On ISU MPICs, sources are counted 1287 * Read feature register. For non-ISU MPICs, num sources as well. On
1290 * as ISUs are added 1288 * ISU MPICs, sources are counted as ISUs are added
1291 */ 1289 */
1292 greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); 1290 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) { 1291 if (isu_size == 0) {
1296 if (flags & MPIC_BROKEN_FRR_NIRQS) 1292 if (flags & MPIC_BROKEN_FRR_NIRQS)
1297 mpic->num_sources = mpic->irq_count; 1293 mpic->num_sources = mpic->irq_count;
@@ -1301,10 +1297,18 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1301 >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; 1297 >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
1302 } 1298 }
1303 1299
1300 /*
1301 * The MPIC driver will crash if there are more cores than we
1302 * can initialize, so we may as well catch that problem here.
1303 */
1304 BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS);
1305
1304 /* Map the per-CPU registers */ 1306 /* Map the per-CPU registers */
1305 for (i = 0; i < mpic->num_cpus; i++) { 1307 for_each_possible_cpu(i) {
1306 mpic_map(mpic, node, paddr, &mpic->cpuregs[i], 1308 unsigned int cpu = get_hard_smp_processor_id(i);
1307 MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), 1309
1310 mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu],
1311 MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
1308 0x1000); 1312 0x1000);
1309 } 1313 }
1310 1314
@@ -1343,7 +1347,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1343 } 1347 }
1344 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," 1348 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
1345 " max %d CPUs\n", 1349 " max %d CPUs\n",
1346 name, vers, (unsigned long long)paddr, mpic->num_cpus); 1350 name, vers, (unsigned long long)paddr, num_possible_cpus());
1347 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", 1351 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
1348 mpic->isu_size, mpic->isu_shift, mpic->isu_mask); 1352 mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
1349 1353
@@ -1742,6 +1746,7 @@ void mpic_reset_core(int cpu)
1742 struct mpic *mpic = mpic_primary; 1746 struct mpic *mpic = mpic_primary;
1743 u32 pir; 1747 u32 pir;
1744 int cpuid = get_hard_smp_processor_id(cpu); 1748 int cpuid = get_hard_smp_processor_id(cpu);
1749 int i;
1745 1750
1746 /* Set target bit for core reset */ 1751 /* Set target bit for core reset */
1747 pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); 1752 pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
@@ -1753,6 +1758,15 @@ void mpic_reset_core(int cpu)
1753 pir &= ~(1 << cpuid); 1758 pir &= ~(1 << cpuid);
1754 mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); 1759 mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
1755 mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); 1760 mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
1761
1762 /* Perform 15 EOI on each reset core to clear pending interrupts.
1763 * This is required for FSL CoreNet based devices */
1764 if (mpic->flags & MPIC_FSL) {
1765 for (i = 0; i < 15; i++) {
1766 _mpic_write(mpic->reg_type, &mpic->cpuregs[cpuid],
1767 MPIC_CPU_EOI, 0);
1768 }
1769 }
1756} 1770}
1757#endif /* CONFIG_SMP */ 1771#endif /* CONFIG_SMP */
1758 1772