diff options
Diffstat (limited to 'arch/cris/arch-v32/kernel/smp.c')
-rw-r--r-- | arch/cris/arch-v32/kernel/smp.c | 31 |
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}; | |||
30 | cpumask_t cpu_online_map = CPU_MASK_NONE; | 32 | cpumask_t cpu_online_map = CPU_MASK_NONE; |
31 | EXPORT_SYMBOL(cpu_online_map); | 33 | EXPORT_SYMBOL(cpu_online_map); |
32 | cpumask_t phys_cpu_present_map = CPU_MASK_NONE; | 34 | cpumask_t phys_cpu_present_map = CPU_MASK_NONE; |
35 | cpumask_t cpu_possible_map; | ||
36 | EXPORT_SYMBOL(cpu_possible_map); | ||
33 | EXPORT_SYMBOL(phys_cpu_present_map); | 37 | EXPORT_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; | |||
55 | extern int setup_irq(int, struct irqaction *); | 59 | extern int setup_irq(int, struct irqaction *); |
56 | 60 | ||
57 | /* Mode registers */ | 61 | /* Mode registers */ |
58 | static unsigned long irq_regs[NR_CPUS] = | 62 | static unsigned long irq_regs[NR_CPUS] = { |
59 | { | ||
60 | regi_irq, | 63 | regi_irq, |
61 | regi_irq2 | 64 | regi_irq2 |
62 | }; | 65 | }; |
63 | 66 | ||
64 | static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 67 | static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id); |
65 | static int send_ipi(int vector, int wait, cpumask_t cpu_mask); | 68 | static int send_ipi(int vector, int wait, cpumask_t cpu_mask); |
66 | static struct irqaction irq_ipi = { | 69 | static 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 | ||
106 | void __init smp_cpus_done(unsigned int max_cpus) | 110 | void __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 | ||
331 | irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 342 | irqreturn_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; |