diff options
Diffstat (limited to 'arch/mips/kernel/smp-bmips.c')
-rw-r--r-- | arch/mips/kernel/smp-bmips.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 8e393b8443f7..aea6c0885838 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c | |||
@@ -63,7 +63,7 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id); | |||
63 | 63 | ||
64 | static void __init bmips_smp_setup(void) | 64 | static void __init bmips_smp_setup(void) |
65 | { | 65 | { |
66 | int i; | 66 | int i, cpu = 1, boot_cpu = 0; |
67 | 67 | ||
68 | #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) | 68 | #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) |
69 | /* arbitration priority */ | 69 | /* arbitration priority */ |
@@ -72,13 +72,22 @@ static void __init bmips_smp_setup(void) | |||
72 | /* NBK and weak order flags */ | 72 | /* NBK and weak order flags */ |
73 | set_c0_brcm_config_0(0x30000); | 73 | set_c0_brcm_config_0(0x30000); |
74 | 74 | ||
75 | /* Find out if we are running on TP0 or TP1 */ | ||
76 | boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31)); | ||
77 | |||
75 | /* | 78 | /* |
76 | * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread | 79 | * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread |
77 | * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output | 80 | * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output |
78 | * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output | 81 | * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output |
82 | * | ||
83 | * If booting from TP1, leave the existing CMT interrupt routing | ||
84 | * such that TP0 responds to SW1 and TP1 responds to SW0. | ||
79 | */ | 85 | */ |
80 | change_c0_brcm_cmt_intr(0xf8018000, | 86 | if (boot_cpu == 0) |
81 | (0x02 << 27) | (0x03 << 15)); | 87 | change_c0_brcm_cmt_intr(0xf8018000, |
88 | (0x02 << 27) | (0x03 << 15)); | ||
89 | else | ||
90 | change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27)); | ||
82 | 91 | ||
83 | /* single core, 2 threads (2 pipelines) */ | 92 | /* single core, 2 threads (2 pipelines) */ |
84 | max_cpus = 2; | 93 | max_cpus = 2; |
@@ -106,9 +115,15 @@ static void __init bmips_smp_setup(void) | |||
106 | if (!board_ebase_setup) | 115 | if (!board_ebase_setup) |
107 | board_ebase_setup = &bmips_ebase_setup; | 116 | board_ebase_setup = &bmips_ebase_setup; |
108 | 117 | ||
118 | __cpu_number_map[boot_cpu] = 0; | ||
119 | __cpu_logical_map[0] = boot_cpu; | ||
120 | |||
109 | for (i = 0; i < max_cpus; i++) { | 121 | for (i = 0; i < max_cpus; i++) { |
110 | __cpu_number_map[i] = 1; | 122 | if (i != boot_cpu) { |
111 | __cpu_logical_map[i] = 1; | 123 | __cpu_number_map[i] = cpu; |
124 | __cpu_logical_map[cpu] = i; | ||
125 | cpu++; | ||
126 | } | ||
112 | set_cpu_possible(i, 1); | 127 | set_cpu_possible(i, 1); |
113 | set_cpu_present(i, 1); | 128 | set_cpu_present(i, 1); |
114 | } | 129 | } |
@@ -157,7 +172,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |||
157 | bmips_send_ipi_single(cpu, 0); | 172 | bmips_send_ipi_single(cpu, 0); |
158 | else { | 173 | else { |
159 | #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) | 174 | #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) |
160 | set_c0_brcm_cmt_ctrl(0x01); | 175 | /* Reset slave TP1 if booting from TP0 */ |
176 | if (cpu_logical_map(cpu) == 0) | ||
177 | set_c0_brcm_cmt_ctrl(0x01); | ||
161 | #elif defined(CONFIG_CPU_BMIPS5000) | 178 | #elif defined(CONFIG_CPU_BMIPS5000) |
162 | if (cpu & 0x01) | 179 | if (cpu & 0x01) |
163 | write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); | 180 | write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); |