aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/smp.c
diff options
context:
space:
mode:
authorSteven Miao <realmz6@gmail.com>2013-07-09 03:39:53 -0400
committerSteven Miao <realmz6@gmail.com>2013-07-09 03:50:38 -0400
commit150382a53d11256e5666c86525c8bf8d23684532 (patch)
tree5a0e5a70ba6006456c4d28ec53e6bf35c353e90c /arch/blackfin/mach-common/smp.c
parentb700a3f304cfc8589f3a5b6012bdd3689b778033 (diff)
smp: refine bf561 smpboot code
release boot lock earlier to let coreb do setup and calibrate set coreb online later after initialization ready add BFIN_IPI_NONE IPI type drop unnecesarry smp_mb() and using atomic type Signed-off-by: Steven Miao <realmz6@gmail.com>
Diffstat (limited to 'arch/blackfin/mach-common/smp.c')
-rw-r--r--arch/blackfin/mach-common/smp.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 1bc2ce6f3c94..961d8392e5e3 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -49,6 +49,7 @@ unsigned long blackfin_iflush_l1_entry[NR_CPUS];
49struct blackfin_initial_pda __cpuinitdata initial_pda_coreb; 49struct blackfin_initial_pda __cpuinitdata initial_pda_coreb;
50 50
51enum ipi_message_type { 51enum ipi_message_type {
52 BFIN_IPI_NONE,
52 BFIN_IPI_TIMER, 53 BFIN_IPI_TIMER,
53 BFIN_IPI_RESCHEDULE, 54 BFIN_IPI_RESCHEDULE,
54 BFIN_IPI_CALL_FUNC, 55 BFIN_IPI_CALL_FUNC,
@@ -72,8 +73,8 @@ static DEFINE_SPINLOCK(stop_lock);
72 73
73/* Simple FIFO buffer, overflow leads to panic */ 74/* Simple FIFO buffer, overflow leads to panic */
74struct ipi_data { 75struct ipi_data {
75 unsigned long count; 76 atomic_t count;
76 unsigned long bits; 77 atomic_t bits;
77}; 78};
78 79
79static DEFINE_PER_CPU(struct ipi_data, bfin_ipi); 80static DEFINE_PER_CPU(struct ipi_data, bfin_ipi);
@@ -146,7 +147,6 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
146 platform_clear_ipi(cpu, IRQ_SUPPLE_1); 147 platform_clear_ipi(cpu, IRQ_SUPPLE_1);
147 148
148 bfin_ipi_data = &__get_cpu_var(bfin_ipi); 149 bfin_ipi_data = &__get_cpu_var(bfin_ipi);
149 smp_mb();
150 while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) { 150 while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) {
151 msg = 0; 151 msg = 0;
152 do { 152 do {
@@ -170,9 +170,8 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
170 ipi_cpu_stop(cpu); 170 ipi_cpu_stop(cpu);
171 break; 171 break;
172 } 172 }
173 atomic_dec(&bfin_ipi_data->count);
173 } while (msg < BITS_PER_LONG); 174 } while (msg < BITS_PER_LONG);
174
175 smp_mb();
176 } 175 }
177 return IRQ_HANDLED; 176 return IRQ_HANDLED;
178} 177}
@@ -195,12 +194,10 @@ void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg)
195 unsigned long flags; 194 unsigned long flags;
196 195
197 local_irq_save(flags); 196 local_irq_save(flags);
198 smp_mb();
199 for_each_cpu(cpu, cpumask) { 197 for_each_cpu(cpu, cpumask) {
200 bfin_ipi_data = &per_cpu(bfin_ipi, cpu); 198 bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
201 smp_mb(); 199 atomic_set_mask((1 << msg), &bfin_ipi_data->bits);
202 set_bit(msg, &bfin_ipi_data->bits); 200 atomic_inc(&bfin_ipi_data->count);
203 bfin_ipi_data->count++;
204 platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1); 201 platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1);
205 } 202 }
206 203
@@ -319,7 +316,6 @@ void __cpuinit secondary_start_kernel(void)
319 setup_secondary(cpu); 316 setup_secondary(cpu);
320 317
321 platform_secondary_init(cpu); 318 platform_secondary_init(cpu);
322
323 /* setup local core timer */ 319 /* setup local core timer */
324 bfin_local_timer_setup(); 320 bfin_local_timer_setup();
325 321
@@ -335,6 +331,8 @@ void __cpuinit secondary_start_kernel(void)
335 */ 331 */
336 calibrate_delay(); 332 calibrate_delay();
337 333
334 /* We are done with local CPU inits, unblock the boot CPU. */
335 set_cpu_online(cpu, true);
338 cpu_startup_entry(CPUHP_ONLINE); 336 cpu_startup_entry(CPUHP_ONLINE);
339} 337}
340 338