aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-bf561
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-bf561')
-rw-r--r--arch/blackfin/mach-bf561/Makefile1
-rw-r--r--arch/blackfin/mach-bf561/hotplug.c32
-rw-r--r--arch/blackfin/mach-bf561/secondary.S50
-rw-r--r--arch/blackfin/mach-bf561/smp.c17
4 files changed, 91 insertions, 9 deletions
diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile
index 59e18afe28c6..b34029718318 100644
--- a/arch/blackfin/mach-bf561/Makefile
+++ b/arch/blackfin/mach-bf561/Makefile
@@ -6,3 +6,4 @@ obj-y := ints-priority.o dma.o
6 6
7obj-$(CONFIG_BF561_COREB) += coreb.o 7obj-$(CONFIG_BF561_COREB) += coreb.o
8obj-$(CONFIG_SMP) += smp.o secondary.o atomic.o 8obj-$(CONFIG_SMP) += smp.o secondary.o atomic.o
9obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/blackfin/mach-bf561/hotplug.c b/arch/blackfin/mach-bf561/hotplug.c
new file mode 100644
index 000000000000..c95169b612dc
--- /dev/null
+++ b/arch/blackfin/mach-bf561/hotplug.c
@@ -0,0 +1,32 @@
1/*
2 * Copyright 2007-2009 Analog Devices Inc.
3 * Graff Yang <graf.yang@analog.com>
4 *
5 * Licensed under the GPL-2 or later.
6 */
7
8#include <asm/blackfin.h>
9#include <asm/smp.h>
10#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1))
11
12int hotplug_coreb;
13
14void platform_cpu_die(void)
15{
16 unsigned long iwr[2] = {0, 0};
17 unsigned long bank = SIC_SYSIRQ(IRQ_SUPPLE_0) / 32;
18 unsigned long bit = 1 << (SIC_SYSIRQ(IRQ_SUPPLE_0) % 32);
19
20 hotplug_coreb = 1;
21
22 iwr[bank] = bit;
23
24 /* disable core timer */
25 bfin_write_TCNTL(0);
26
27 /* clear ipi interrupt IRQ_SUPPLE_0 */
28 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + 1)));
29 SSYNC();
30
31 coreb_sleep(iwr[0], iwr[1], 0);
32}
diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S
index 8e6050369c06..4624eebbf9c4 100644
--- a/arch/blackfin/mach-bf561/secondary.S
+++ b/arch/blackfin/mach-bf561/secondary.S
@@ -11,6 +11,7 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <asm/blackfin.h> 12#include <asm/blackfin.h>
13#include <asm/asm-offsets.h> 13#include <asm/asm-offsets.h>
14#include <asm/trace.h>
14 15
15__INIT 16__INIT
16 17
@@ -62,6 +63,8 @@ ENTRY(_coreb_trampoline_start)
62 M2 = r0; 63 M2 = r0;
63 M3 = r0; 64 M3 = r0;
64 65
66 trace_buffer_init(p0,r0);
67
65 /* Turn off the icache */ 68 /* Turn off the icache */
66 p0.l = LO(IMEM_CONTROL); 69 p0.l = LO(IMEM_CONTROL);
67 p0.h = HI(IMEM_CONTROL); 70 p0.h = HI(IMEM_CONTROL);
@@ -159,6 +162,41 @@ ENTRY(_coreb_trampoline_start)
159ENDPROC(_coreb_trampoline_start) 162ENDPROC(_coreb_trampoline_start)
160ENTRY(_coreb_trampoline_end) 163ENTRY(_coreb_trampoline_end)
161 164
165.section ".text"
166ENTRY(_set_sicb_iwr)
167 P0.H = hi(SICB_IWR0);
168 P0.L = lo(SICB_IWR0);
169 P1.H = hi(SICB_IWR1);
170 P1.L = lo(SICB_IWR1);
171 [P0] = R0;
172 [P1] = R1;
173 SSYNC;
174 RTS;
175ENDPROC(_set_sicb_iwr)
176
177ENTRY(_coreb_sleep)
178 sp.l = lo(INITIAL_STACK);
179 sp.h = hi(INITIAL_STACK);
180 fp = sp;
181 usp = sp;
182
183 call _set_sicb_iwr;
184
185 CLI R2;
186 SSYNC;
187 IDLE;
188 STI R2;
189
190 R0 = IWR_DISABLE_ALL;
191 R1 = IWR_DISABLE_ALL;
192 call _set_sicb_iwr;
193
194 p0.h = hi(COREB_L1_CODE_START);
195 p0.l = lo(COREB_L1_CODE_START);
196 jump (p0);
197ENDPROC(_coreb_sleep)
198
199__CPUINIT
162ENTRY(_coreb_start) 200ENTRY(_coreb_start)
163 [--sp] = reti; 201 [--sp] = reti;
164 202
@@ -176,12 +214,20 @@ ENTRY(_coreb_start)
176 sp = [p0]; 214 sp = [p0];
177 usp = sp; 215 usp = sp;
178 fp = sp; 216 fp = sp;
217#ifdef CONFIG_HOTPLUG_CPU
218 p0.l = _hotplug_coreb;
219 p0.h = _hotplug_coreb;
220 r0 = [p0];
221 cc = BITTST(r0, 0);
222 if cc jump 3f;
223#endif
179 sp += -12; 224 sp += -12;
180 call _init_pda 225 call _init_pda
181 sp += 12; 226 sp += 12;
227#ifdef CONFIG_HOTPLUG_CPU
2283:
229#endif
182 call _secondary_start_kernel; 230 call _secondary_start_kernel;
183.L_exit: 231.L_exit:
184 jump.s .L_exit; 232 jump.s .L_exit;
185ENDPROC(_coreb_start) 233ENDPROC(_coreb_start)
186
187__FINIT
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index 90369429ee66..3b9a4bf7dacc 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -65,6 +65,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
65 bfin_write_SICB_IAR5(bfin_read_SICA_IAR5()); 65 bfin_write_SICB_IAR5(bfin_read_SICA_IAR5());
66 bfin_write_SICB_IAR6(bfin_read_SICA_IAR6()); 66 bfin_write_SICB_IAR6(bfin_read_SICA_IAR6());
67 bfin_write_SICB_IAR7(bfin_read_SICA_IAR7()); 67 bfin_write_SICB_IAR7(bfin_read_SICA_IAR7());
68 bfin_write_SICB_IWR0(IWR_DISABLE_ALL);
69 bfin_write_SICB_IWR1(IWR_DISABLE_ALL);
68 SSYNC(); 70 SSYNC();
69 71
70 /* Store CPU-private information to the cpu_data array. */ 72 /* Store CPU-private information to the cpu_data array. */
@@ -80,17 +82,18 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
80{ 82{
81 unsigned long timeout; 83 unsigned long timeout;
82 84
83 /* CoreB already running?! */
84 BUG_ON((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0);
85
86 printk(KERN_INFO "Booting Core B.\n"); 85 printk(KERN_INFO "Booting Core B.\n");
87 86
88 spin_lock(&boot_lock); 87 spin_lock(&boot_lock);
89 88
90 /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */ 89 if ((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0) {
91 SSYNC(); 90 /* CoreB already running, sending ipi to wakeup it */
92 bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT); 91 platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0);
93 SSYNC(); 92 } else {
93 /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
94 bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT);
95 SSYNC();
96 }
94 97
95 timeout = jiffies + 1 * HZ; 98 timeout = jiffies + 1 * HZ;
96 while (time_before(jiffies, timeout)) { 99 while (time_before(jiffies, timeout)) {