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>
This commit is contained in:
@@ -69,7 +69,6 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
|
|||||||
SSYNC();
|
SSYNC();
|
||||||
|
|
||||||
/* We are done with local CPU inits, unblock the boot CPU. */
|
/* We are done with local CPU inits, unblock the boot CPU. */
|
||||||
set_cpu_online(cpu, true);
|
|
||||||
spin_lock(&boot_lock);
|
spin_lock(&boot_lock);
|
||||||
spin_unlock(&boot_lock);
|
spin_unlock(&boot_lock);
|
||||||
}
|
}
|
||||||
@@ -91,7 +90,9 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
|
|||||||
SSYNC();
|
SSYNC();
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout = jiffies + 1 * HZ;
|
timeout = jiffies + HZ;
|
||||||
|
/* release the lock and let coreb run */
|
||||||
|
spin_unlock(&boot_lock);
|
||||||
while (time_before(jiffies, timeout)) {
|
while (time_before(jiffies, timeout)) {
|
||||||
if (cpu_online(cpu))
|
if (cpu_online(cpu))
|
||||||
break;
|
break;
|
||||||
@@ -100,8 +101,6 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cpu_online(cpu)) {
|
if (cpu_online(cpu)) {
|
||||||
/* release the lock and let coreb run */
|
|
||||||
spin_unlock(&boot_lock);
|
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
panic("CPU%u: processor failed to boot\n", cpu);
|
panic("CPU%u: processor failed to boot\n", cpu);
|
||||||
|
@@ -49,6 +49,7 @@ unsigned long blackfin_iflush_l1_entry[NR_CPUS];
|
|||||||
struct blackfin_initial_pda __cpuinitdata initial_pda_coreb;
|
struct blackfin_initial_pda __cpuinitdata initial_pda_coreb;
|
||||||
|
|
||||||
enum ipi_message_type {
|
enum ipi_message_type {
|
||||||
|
BFIN_IPI_NONE,
|
||||||
BFIN_IPI_TIMER,
|
BFIN_IPI_TIMER,
|
||||||
BFIN_IPI_RESCHEDULE,
|
BFIN_IPI_RESCHEDULE,
|
||||||
BFIN_IPI_CALL_FUNC,
|
BFIN_IPI_CALL_FUNC,
|
||||||
@@ -72,8 +73,8 @@ static DEFINE_SPINLOCK(stop_lock);
|
|||||||
|
|
||||||
/* Simple FIFO buffer, overflow leads to panic */
|
/* Simple FIFO buffer, overflow leads to panic */
|
||||||
struct ipi_data {
|
struct ipi_data {
|
||||||
unsigned long count;
|
atomic_t count;
|
||||||
unsigned long bits;
|
atomic_t bits;
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_PER_CPU(struct ipi_data, bfin_ipi);
|
static DEFINE_PER_CPU(struct ipi_data, bfin_ipi);
|
||||||
@@ -146,7 +147,6 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
|
|||||||
platform_clear_ipi(cpu, IRQ_SUPPLE_1);
|
platform_clear_ipi(cpu, IRQ_SUPPLE_1);
|
||||||
|
|
||||||
bfin_ipi_data = &__get_cpu_var(bfin_ipi);
|
bfin_ipi_data = &__get_cpu_var(bfin_ipi);
|
||||||
smp_mb();
|
|
||||||
while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) {
|
while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) {
|
||||||
msg = 0;
|
msg = 0;
|
||||||
do {
|
do {
|
||||||
@@ -170,9 +170,8 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
|
|||||||
ipi_cpu_stop(cpu);
|
ipi_cpu_stop(cpu);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
atomic_dec(&bfin_ipi_data->count);
|
||||||
} while (msg < BITS_PER_LONG);
|
} while (msg < BITS_PER_LONG);
|
||||||
|
|
||||||
smp_mb();
|
|
||||||
}
|
}
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
@@ -195,12 +194,10 @@ void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
smp_mb();
|
|
||||||
for_each_cpu(cpu, cpumask) {
|
for_each_cpu(cpu, cpumask) {
|
||||||
bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
|
bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
|
||||||
smp_mb();
|
atomic_set_mask((1 << msg), &bfin_ipi_data->bits);
|
||||||
set_bit(msg, &bfin_ipi_data->bits);
|
atomic_inc(&bfin_ipi_data->count);
|
||||||
bfin_ipi_data->count++;
|
|
||||||
platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1);
|
platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +316,6 @@ void __cpuinit secondary_start_kernel(void)
|
|||||||
setup_secondary(cpu);
|
setup_secondary(cpu);
|
||||||
|
|
||||||
platform_secondary_init(cpu);
|
platform_secondary_init(cpu);
|
||||||
|
|
||||||
/* setup local core timer */
|
/* setup local core timer */
|
||||||
bfin_local_timer_setup();
|
bfin_local_timer_setup();
|
||||||
|
|
||||||
@@ -335,6 +331,8 @@ void __cpuinit secondary_start_kernel(void)
|
|||||||
*/
|
*/
|
||||||
calibrate_delay();
|
calibrate_delay();
|
||||||
|
|
||||||
|
/* We are done with local CPU inits, unblock the boot CPU. */
|
||||||
|
set_cpu_online(cpu, true);
|
||||||
cpu_startup_entry(CPUHP_ONLINE);
|
cpu_startup_entry(CPUHP_ONLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user