summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChen-Hui Zhao <chenhui.zhao@freescale.com>2012-11-20 18:15:14 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-03-26 23:14:41 (GMT)
commit4c813a0a8e5deb6dcb2d19aeb43be469a7dfbf15 (patch)
tree852960f066e7877f16c0545a553ccd7d94824f88
parent06cfc73c79d040637cdfcc690dfc8f4ffd75d2ce (diff)
downloadlinux-fsl-qoriq-4c813a0a8e5deb6dcb2d19aeb43be469a7dfbf15.tar.xz
powerpc/85xx: fix 64-bit support for cpu hotplug
* The paca[cpu].cpu_start is used as a signal to indicate if the cpu should start. So it should be cleard in .cpu_die(). * The limit memory routine only needs to be ran once at boot time by the boot cpu. Prevent other cpus running it again. * Rearrange the code segment in smp_85xx_kick_cpu() to share codes between PPC64 and PPC32 as far as possible. Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com> Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Andy Fleming <afleming@freescale.com> Change-Id: I6a3c45d8645b12884695bd64fb85d1331798cd3f Reviewed-on: http://git.am.freescale.net:8181/560 Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/kernel/smp.c3
-rw-r--r--arch/powerpc/mm/tlb_nohash.c6
-rw-r--r--arch/powerpc/platforms/85xx/smp.c23
4 files changed, 19 insertions, 15 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b06e65d..5e14d1a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -339,7 +339,7 @@ config SWIOTLB
config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
depends on SMP && HOTPLUG && (PPC_PSERIES || \
- PPC_PMAC || PPC_POWERNV || PPC_85xx)
+ PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE)
---help---
Say Y here to be able to disable and re-enable individual
CPUs at runtime on SMP machines.
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d0018c5..e6f5d08 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -424,6 +424,9 @@ void generic_cpu_die(unsigned int cpu)
smp_rmb();
if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
platform_cpu_die(cpu);
+#ifdef CONFIG_PPC64
+ paca[cpu].cpu_start = 0;
+#endif
return;
}
msleep(100);
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index a6979a5..fca908b 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -676,8 +676,10 @@ static void __early_init_mmu(int boot_cpu)
num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
linear_map_top = map_mem_in_cams(linear_map_top, num_cams);
- /* limit memory so we dont have linear faults */
- memblock_enforce_memory_limit(linear_map_top);
+ if (boot_cpu) {
+ /* limit memory so we dont have linear faults */
+ memblock_enforce_memory_limit(linear_map_top);
+ }
if (book3e_htw_mode == PPC_HTW_NONE) {
patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 7f7619f..5fa5517 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -260,10 +260,6 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
spin_table = phys_to_virt(*cpu_rel_addr);
local_irq_save(flags);
-#ifdef CONFIG_PPC32
-#ifdef CONFIG_HOTPLUG_CPU
- /* Corresponding to generic_set_cpu_dead() */
- generic_set_cpu_up(nr);
if (system_state == SYSTEM_RUNNING) {
/*
@@ -308,12 +304,19 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
/* clear the acknowledge status */
__secondary_hold_acknowledge = -1;
}
-#endif
flush_spin_table(spin_table);
out_be32(&spin_table->pir, hw_cpu);
+#ifdef CONFIG_PPC32
out_be32(&spin_table->addr_l, __pa(__early_start));
+#else
+ out_be32(&spin_table->addr_h,
+ __pa(*(u64 *)generic_secondary_smp_init) >> 32);
+ out_be32(&spin_table->addr_l,
+ __pa(*(u64 *)generic_secondary_smp_init) & 0xffffffff);
+#endif
flush_spin_table(spin_table);
+#ifdef CONFIG_PPC32
/* Wait a bit for the CPU to ack. */
if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu,
10000, 100)) {
@@ -322,18 +325,14 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
ret = -ENOENT;
goto out;
}
-out:
#else
smp_generic_kick_cpu(nr);
-
- flush_spin_table(spin_table);
- out_be32(&spin_table->pir, hw_cpu);
- out_be64((u64 *)(&spin_table->addr_h),
- __pa((u64)*((unsigned long long *)generic_secondary_smp_init)));
- flush_spin_table(spin_table);
#endif
+ /* Corresponding to generic_set_cpu_dead() */
+ generic_set_cpu_up(nr);
cur_booting_core = hw_cpu;
+out:
local_irq_restore(flags);
if (ioremappable)