summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/mpic.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-06 17:12:03 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-06 17:12:03 -0800
commit1197ab2942f920f261952de0c392ac749a35796b (patch)
tree4922ccc8a6061e5ece6ac7420001f3bf4524ea92 /arch/powerpc/sysdev/mpic.c
parentec773e99ab4abce07b1ae23117179c2861831964 (diff)
parent96cc017c5b7ec095ef047d3c1952b6b6bbf98943 (diff)
downloadtalos-op-linux-1197ab2942f920f261952de0c392ac749a35796b.tar.gz
talos-op-linux-1197ab2942f920f261952de0c392ac749a35796b.zip
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (106 commits) powerpc/p3060qds: Add support for P3060QDS board powerpc/83xx: Add shutdown request support to MCU handling on MPC8349 MITX powerpc/85xx: Make kexec to interate over online cpus powerpc/fsl_booke: Fix comment in head_fsl_booke.S powerpc/85xx: issue 15 EOI after core reset for FSL CoreNet devices powerpc/8xxx: Fix interrupt handling in MPC8xxx GPIO driver powerpc/85xx: Add 'fsl,pq3-gpio' compatiable for GPIO driver powerpc/86xx: Correct Gianfar support for GE boards powerpc/cpm: Clear muram before it is in use. drivers/virt: add ioctl for 32-bit compat on 64-bit to fsl-hv-manager powerpc/fsl_msi: add support for "msi-address-64" property powerpc/85xx: Setup secondary cores PIR with hard SMP id powerpc/fsl-booke: Fix settlbcam for 64-bit powerpc/85xx: Adding DCSR node to dtsi device trees powerpc/85xx: clean up FPGA device tree nodes for Freecsale QorIQ boards powerpc/85xx: fix PHYS_64BIT selection for P1022DS powerpc/fsl-booke: Fix setup_initial_memory_limit to not blindly map powerpc: respect mem= setting for early memory limit setup powerpc: Update corenet64_smp_defconfig powerpc: Update mpc85xx/corenet 32-bit defconfigs ... Fix up trivial conflicts in: - arch/powerpc/configs/40x/hcu4_defconfig removed stale file, edited elsewhere - arch/powerpc/include/asm/udbg.h, arch/powerpc/kernel/udbg.c: added opal and gelic drivers vs added ePAPR driver - drivers/tty/serial/8250.c moved UPIO_TSI to powerpc vs removed UPIO_DWAPB support
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r--arch/powerpc/sysdev/mpic.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index d5d3ff3d757e..0842c6f8a3e6 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,
mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
| MPIC_GREG_GCONF_MCK);
- /* Read feature register, calculate num CPUs and, for non-ISU
- * MPICs, num sources as well. On ISU MPICs, sources are counted
- * as ISUs are added
+ /*
+ * Read feature register. For non-ISU MPICs, num sources as well. On
+ * ISU MPICs, sources are counted as ISUs are added
*/
greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
- mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK)
- >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
if (isu_size == 0) {
if (flags & MPIC_BROKEN_FRR_NIRQS)
mpic->num_sources = mpic->irq_count;
@@ -1301,10 +1299,18 @@ struct mpic * __init mpic_alloc(struct device_node *node,
>> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
}
+ /*
+ * The MPIC driver will crash if there are more cores than we
+ * can initialize, so we may as well catch that problem here.
+ */
+ BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS);
+
/* Map the per-CPU registers */
- for (i = 0; i < mpic->num_cpus; i++) {
- mpic_map(mpic, node, paddr, &mpic->cpuregs[i],
- MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE),
+ for_each_possible_cpu(i) {
+ unsigned int cpu = get_hard_smp_processor_id(i);
+
+ mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu],
+ MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
0x1000);
}
@@ -1343,7 +1349,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
}
printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
" max %d CPUs\n",
- name, vers, (unsigned long long)paddr, mpic->num_cpus);
+ name, vers, (unsigned long long)paddr, num_possible_cpus());
printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
@@ -1742,6 +1748,7 @@ void mpic_reset_core(int cpu)
struct mpic *mpic = mpic_primary;
u32 pir;
int cpuid = get_hard_smp_processor_id(cpu);
+ int i;
/* Set target bit for core reset */
pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
@@ -1753,6 +1760,15 @@ void mpic_reset_core(int cpu)
pir &= ~(1 << cpuid);
mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
+
+ /* Perform 15 EOI on each reset core to clear pending interrupts.
+ * This is required for FSL CoreNet based devices */
+ if (mpic->flags & MPIC_FSL) {
+ for (i = 0; i < 15; i++) {
+ _mpic_write(mpic->reg_type, &mpic->cpuregs[cpuid],
+ MPIC_CPU_EOI, 0);
+ }
+ }
}
#endif /* CONFIG_SMP */
OpenPOWER on IntegriCloud