aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris')
-rw-r--r--arch/cris/arch-v32/kernel/smp.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 171c96e0a5d3..a9c3334e46c9 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -1,11 +1,12 @@
1#include <linux/types.h>
1#include <asm/delay.h> 2#include <asm/delay.h>
2#include <asm/arch/irq.h> 3#include <irq.h>
3#include <asm/arch/hwregs/intr_vect.h> 4#include <hwregs/intr_vect.h>
4#include <asm/arch/hwregs/intr_vect_defs.h> 5#include <hwregs/intr_vect_defs.h>
5#include <asm/tlbflush.h> 6#include <asm/tlbflush.h>
6#include <asm/mmu_context.h> 7#include <asm/mmu_context.h>
7#include <asm/arch/hwregs/mmu_defs_asm.h> 8#include <hwregs/asm/mmu_defs_asm.h>
8#include <asm/arch/hwregs/supp_reg.h> 9#include <hwregs/supp_reg.h>
9#include <asm/atomic.h> 10#include <asm/atomic.h>
10 11
11#include <linux/err.h> 12#include <linux/err.h>
@@ -20,6 +21,7 @@
20#define IPI_SCHEDULE 1 21#define IPI_SCHEDULE 1
21#define IPI_CALL 2 22#define IPI_CALL 2
22#define IPI_FLUSH_TLB 4 23#define IPI_FLUSH_TLB 4
24#define IPI_BOOT 8
23 25
24#define FLUSH_ALL (void*)0xffffffff 26#define FLUSH_ALL (void*)0xffffffff
25 27
@@ -30,6 +32,8 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
30cpumask_t cpu_online_map = CPU_MASK_NONE; 32cpumask_t cpu_online_map = CPU_MASK_NONE;
31EXPORT_SYMBOL(cpu_online_map); 33EXPORT_SYMBOL(cpu_online_map);
32cpumask_t phys_cpu_present_map = CPU_MASK_NONE; 34cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
35cpumask_t cpu_possible_map;
36EXPORT_SYMBOL(cpu_possible_map);
33EXPORT_SYMBOL(phys_cpu_present_map); 37EXPORT_SYMBOL(phys_cpu_present_map);
34 38
35/* Variables used during SMP boot */ 39/* Variables used during SMP boot */
@@ -55,13 +59,12 @@ static unsigned long flush_addr;
55extern int setup_irq(int, struct irqaction *); 59extern int setup_irq(int, struct irqaction *);
56 60
57/* Mode registers */ 61/* Mode registers */
58static unsigned long irq_regs[NR_CPUS] = 62static unsigned long irq_regs[NR_CPUS] = {
59{
60 regi_irq, 63 regi_irq,
61 regi_irq2 64 regi_irq2
62}; 65};
63 66
64static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs); 67static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id);
65static int send_ipi(int vector, int wait, cpumask_t cpu_mask); 68static int send_ipi(int vector, int wait, cpumask_t cpu_mask);
66static struct irqaction irq_ipi = { 69static struct irqaction irq_ipi = {
67 .handler = crisv32_ipi_interrupt, 70 .handler = crisv32_ipi_interrupt,
@@ -101,6 +104,7 @@ void __devinit smp_prepare_boot_cpu(void)
101 104
102 cpu_set(0, cpu_online_map); 105 cpu_set(0, cpu_online_map);
103 cpu_set(0, phys_cpu_present_map); 106 cpu_set(0, phys_cpu_present_map);
107 cpu_set(0, cpu_possible_map);
104} 108}
105 109
106void __init smp_cpus_done(unsigned int max_cpus) 110void __init smp_cpus_done(unsigned int max_cpus)
@@ -113,6 +117,7 @@ smp_boot_one_cpu(int cpuid)
113{ 117{
114 unsigned timeout; 118 unsigned timeout;
115 struct task_struct *idle; 119 struct task_struct *idle;
120 cpumask_t cpu_mask = CPU_MASK_NONE;
116 121
117 idle = fork_idle(cpuid); 122 idle = fork_idle(cpuid);
118 if (IS_ERR(idle)) 123 if (IS_ERR(idle))
@@ -124,6 +129,12 @@ smp_boot_one_cpu(int cpuid)
124 smp_init_current_idle_thread = task_thread_info(idle); 129 smp_init_current_idle_thread = task_thread_info(idle);
125 cpu_now_booting = cpuid; 130 cpu_now_booting = cpuid;
126 131
132 /* Kick it */
133 cpu_set(cpuid, cpu_online_map);
134 cpu_set(cpuid, cpu_mask);
135 send_ipi(IPI_BOOT, 0, cpu_mask);
136 cpu_clear(cpuid, cpu_online_map);
137
127 /* Wait for CPU to come online */ 138 /* Wait for CPU to come online */
128 for (timeout = 0; timeout < 10000; timeout++) { 139 for (timeout = 0; timeout < 10000; timeout++) {
129 if(cpu_online(cpuid)) { 140 if(cpu_online(cpuid)) {
@@ -165,7 +176,7 @@ void __init smp_callin(void)
165 /* Enable IRQ and idle */ 176 /* Enable IRQ and idle */
166 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); 177 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask);
167 unmask_irq(IPI_INTR_VECT); 178 unmask_irq(IPI_INTR_VECT);
168 unmask_irq(TIMER_INTR_VECT); 179 unmask_irq(TIMER0_INTR_VECT);
169 preempt_disable(); 180 preempt_disable();
170 local_irq_enable(); 181 local_irq_enable();
171 182
@@ -328,7 +339,7 @@ int smp_call_function(void (*func)(void *info), void *info,
328 return ret; 339 return ret;
329} 340}
330 341
331irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs) 342irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id)
332{ 343{
333 void (*func) (void *info) = call_data->func; 344 void (*func) (void *info) = call_data->func;
334 void *info = call_data->info; 345 void *info = call_data->info;