aboutsummaryrefslogtreecommitdiff
path: root/arch/blackfin/mach-bf561/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-bf561/smp.c')
-rw-r--r--arch/blackfin/mach-bf561/smp.c75
1 files changed, 40 insertions, 35 deletions
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index f540ed1257d..11789beca75 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -24,24 +24,23 @@ static DEFINE_SPINLOCK(boot_lock);
void __init platform_init_cpus(void)
{
- cpu_set(0, cpu_possible_map); /* CoreA */
- cpu_set(1, cpu_possible_map); /* CoreB */
+ struct cpumask mask;
+
+ cpumask_set_cpu(0, &mask); /* CoreA */
+ cpumask_set_cpu(1, &mask); /* CoreB */
+ init_cpu_possible(&mask);
}
void __init platform_prepare_cpus(unsigned int max_cpus)
{
- int len;
-
- len = &coreb_trampoline_end - &coreb_trampoline_start + 1;
- BUG_ON(len > L1_CODE_LENGTH);
+ struct cpumask mask;
- dma_memcpy((void *)COREB_L1_CODE_START, &coreb_trampoline_start, len);
+ bfin_relocate_coreb_l1_mem();
/* Both cores ought to be present on a bf561! */
- cpu_set(0, cpu_present_map); /* CoreA */
- cpu_set(1, cpu_present_map); /* CoreB */
-
- printk(KERN_INFO "CoreB bootstrap code to SRAM %p via DMA.\n", (void *)COREB_L1_CODE_START);
+ cpumask_set_cpu(0, &mask); /* CoreA */
+ cpumask_set_cpu(1, &mask); /* CoreB */
+ init_cpu_present(&mask);
}
int __init setup_profiling_timer(unsigned int multiplier) /* not supported */
@@ -49,7 +48,7 @@ int __init setup_profiling_timer(unsigned int multiplier) /* not supported */
return -EINVAL;
}
-void __cpuinit platform_secondary_init(unsigned int cpu)
+void platform_secondary_init(unsigned int cpu)
{
/* Clone setup for peripheral interrupt sources from CoreA. */
bfin_write_SICB_IMASK0(bfin_read_SIC_IMASK0());
@@ -69,16 +68,12 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
bfin_write_SICB_IWR1(IWR_DISABLE_ALL);
SSYNC();
- /* Store CPU-private information to the cpu_data array. */
- bfin_setup_cpudata(cpu);
-
/* We are done with local CPU inits, unblock the boot CPU. */
- set_cpu_online(cpu, true);
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
}
-int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle)
+int platform_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
@@ -86,16 +81,18 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
spin_lock(&boot_lock);
- if ((bfin_read_SIC_SYSCR() & COREB_SRAM_INIT) == 0) {
+ if ((bfin_read_SYSCR() & COREB_SRAM_INIT) == 0) {
/* CoreB already running, sending ipi to wakeup it */
- platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0);
+ smp_send_reschedule(cpu);
} else {
/* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
- bfin_write_SIC_SYSCR(bfin_read_SIC_SYSCR() & ~COREB_SRAM_INIT);
+ bfin_write_SYSCR(bfin_read_SYSCR() & ~COREB_SRAM_INIT);
SSYNC();
}
- timeout = jiffies + 1 * HZ;
+ timeout = jiffies + HZ;
+ /* release the lock and let coreb run */
+ spin_unlock(&boot_lock);
while (time_before(jiffies, timeout)) {
if (cpu_online(cpu))
break;
@@ -104,48 +101,52 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
}
if (cpu_online(cpu)) {
- /* release the lock and let coreb run */
- spin_unlock(&boot_lock);
return 0;
} else
panic("CPU%u: processor failed to boot\n", cpu);
}
-void __init platform_request_ipi(irq_handler_t handler)
+static const char supple0[] = "IRQ_SUPPLE_0";
+static const char supple1[] = "IRQ_SUPPLE_1";
+void __init platform_request_ipi(int irq, void *handler)
{
int ret;
+ const char *name = (irq == IRQ_SUPPLE_0) ? supple0 : supple1;
- ret = request_irq(IRQ_SUPPLE_0, handler, IRQF_DISABLED,
- "Supplemental Interrupt0", handler);
+ ret = request_irq(irq, handler, IRQF_PERCPU | IRQF_NO_SUSPEND |
+ IRQF_FORCE_RESUME, name, handler);
if (ret)
- panic("Cannot request supplemental interrupt 0 for IPI service");
+ panic("Cannot request %s for IPI service", name);
}
-void platform_send_ipi(cpumask_t callmap)
+void platform_send_ipi(cpumask_t callmap, int irq)
{
unsigned int cpu;
+ int offset = (irq == IRQ_SUPPLE_0) ? 6 : 8;
for_each_cpu_mask(cpu, callmap) {
BUG_ON(cpu >= 2);
SSYNC();
- bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (6 + cpu)));
+ bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (offset + cpu)));
SSYNC();
}
}
-void platform_send_ipi_cpu(unsigned int cpu)
+void platform_send_ipi_cpu(unsigned int cpu, int irq)
{
+ int offset = (irq == IRQ_SUPPLE_0) ? 6 : 8;
BUG_ON(cpu >= 2);
SSYNC();
- bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (6 + cpu)));
+ bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (offset + cpu)));
SSYNC();
}
-void platform_clear_ipi(unsigned int cpu)
+void platform_clear_ipi(unsigned int cpu, int irq)
{
+ int offset = (irq == IRQ_SUPPLE_0) ? 10 : 12;
BUG_ON(cpu >= 2);
SSYNC();
- bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + cpu)));
+ bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (offset + cpu)));
SSYNC();
}
@@ -153,12 +154,16 @@ void platform_clear_ipi(unsigned int cpu)
* Setup core B's local core timer.
* In SMP, core timer is used for clock event device.
*/
-void __cpuinit bfin_local_timer_setup(void)
+void bfin_local_timer_setup(void)
{
#if defined(CONFIG_TICKSOURCE_CORETMR)
+ struct irq_data *data = irq_get_irq_data(IRQ_CORETMR);
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
+
bfin_coretmr_init();
bfin_coretmr_clockevent_init();
- get_irq_chip(IRQ_CORETMR)->unmask(IRQ_CORETMR);
+
+ chip->irq_unmask(data);
#else
/* Power down the core timer, just to play safe. */
bfin_write_TCNTL(0);