summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/smp-bmips.c
diff options
context:
space:
mode:
authorFlorian Fainelli <florian@openwrt.org>2013-07-24 18:12:11 +0200
committerRalf Baechle <ralf@linux-mips.org>2013-07-30 18:54:29 +0200
commitff5fadaff39180dc0b652753b5614a564711be29 (patch)
tree07662c3a1f58bd8355a4f7d3da23c2962f15be07 /arch/mips/kernel/smp-bmips.c
parentMIPS: BMIPS: do not change interrupt routing depending on boot CPU (diff)
downloadlinux-ff5fadaff39180dc0b652753b5614a564711be29.tar.xz
linux-ff5fadaff39180dc0b652753b5614a564711be29.zip
MIPS: BMIPS: fix slave CPU booting when physical CPU is not 0
The current BMIPS SMP code assumes that the slave CPU is physical and logical CPU 1, but on some systems such as BCM3368, the slave CPU is physical CPU0. Fix the code to read the physical CPU (thread ID) we are running this code on, and adjust the relocation vector address based on it. This allows bringing up the second CPU on BCM3368 for instance. Signed-off-by: Florian Fainelli <florian@openwrt.org> Cc: linux-mips@linux-mips.org Cc: cernekee@gmail.com Cc: jogo@openwrt.org Cc: blogic@openwrt.org Patchwork: https://patchwork.linux-mips.org/patch/5621/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to '')
-rw-r--r--arch/mips/kernel/smp-bmips.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 89417c9c6aca..159abc8842d2 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -196,9 +196,15 @@ static void bmips_init_secondary(void)
#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
void __iomem *cbr = BMIPS_GET_CBR();
unsigned long old_vec;
+ unsigned long relo_vector;
+ int boot_cpu;
- old_vec = __raw_readl(cbr + BMIPS_RELO_VECTOR_CONTROL_1);
- __raw_writel(old_vec & ~0x20000000, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+ boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
+ relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
+ BMIPS_RELO_VECTOR_CONTROL_1;
+
+ old_vec = __raw_readl(cbr + relo_vector);
+ __raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
#elif defined(CONFIG_CPU_BMIPS5000)