diff options
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 36 |
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 | ||