diff options
Diffstat (limited to 'arch/blackfin/mach-bf561')
-rw-r--r-- | arch/blackfin/mach-bf561/boards/cm_bf561.c | 2 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/hotplug.c | 26 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/secondary.S | 35 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/smp.c | 15 |
4 files changed, 38 insertions, 40 deletions
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c index 3b67929d4c0..87595cd38af 100644 --- a/arch/blackfin/mach-bf561/boards/cm_bf561.c +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c @@ -541,7 +541,7 @@ static int __init cm_bf561_init(void) #endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) - irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; + irq_set_status_flags(PATA_INT, IRQ_NOAUTOEN); #endif return 0; } diff --git a/arch/blackfin/mach-bf561/hotplug.c b/arch/blackfin/mach-bf561/hotplug.c index 4cd3b28cd04..0123117b8ff 100644 --- a/arch/blackfin/mach-bf561/hotplug.c +++ b/arch/blackfin/mach-bf561/hotplug.c @@ -5,30 +5,36 @@ * Licensed under the GPL-2 or later. */ +#include <linux/smp.h> #include <asm/blackfin.h> -#include <asm/irq.h> -#include <asm/smp.h> - -#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) +#include <asm/cacheflush.h> +#include <mach/pll.h> int hotplug_coreb; void platform_cpu_die(void) { - unsigned long iwr[2] = {0, 0}; - unsigned long bank = SIC_SYSIRQ(IRQ_SUPPLE_0) / 32; - unsigned long bit = 1 << (SIC_SYSIRQ(IRQ_SUPPLE_0) % 32); + unsigned long iwr; hotplug_coreb = 1; - iwr[bank] = bit; + /* + * When CoreB wakes up, the code in _coreb_trampoline_start cannot + * turn off the data cache. This causes the CoreB failed to boot. + * As a workaround, we invalidate all the data cache before sleep. + */ + blackfin_invalidate_entire_dcache(); /* disable core timer */ bfin_write_TCNTL(0); - /* clear ipi interrupt IRQ_SUPPLE_0 */ + /* clear ipi interrupt IRQ_SUPPLE_0 of CoreB */ bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + 1))); SSYNC(); - coreb_sleep(iwr[0], iwr[1], 0); + /* set CoreB wakeup by ipi0, iwr will be discarded */ + bfin_iwr_set_sup0(&iwr, &iwr, &iwr); + SSYNC(); + + coreb_die(); } diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S index 4624eebbf9c..4c462838f4e 100644 --- a/arch/blackfin/mach-bf561/secondary.S +++ b/arch/blackfin/mach-bf561/secondary.S @@ -13,7 +13,11 @@ #include <asm/asm-offsets.h> #include <asm/trace.h> -__INIT +/* + * This code must come first as CoreB is hardcoded (in hardware) + * to start at the beginning of its L1 instruction memory. + */ +.section .l1.text.head /* Lay the initial stack into the L1 scratch area of Core B */ #define INITIAL_STACK (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) @@ -160,43 +164,34 @@ ENTRY(_coreb_trampoline_start) .LWAIT_HERE: jump .LWAIT_HERE; ENDPROC(_coreb_trampoline_start) -ENTRY(_coreb_trampoline_end) +#ifdef CONFIG_HOTPLUG_CPU .section ".text" -ENTRY(_set_sicb_iwr) - P0.H = hi(SICB_IWR0); - P0.L = lo(SICB_IWR0); - P1.H = hi(SICB_IWR1); - P1.L = lo(SICB_IWR1); - [P0] = R0; - [P1] = R1; - SSYNC; - RTS; -ENDPROC(_set_sicb_iwr) - -ENTRY(_coreb_sleep) +ENTRY(_coreb_die) sp.l = lo(INITIAL_STACK); sp.h = hi(INITIAL_STACK); fp = sp; usp = sp; - call _set_sicb_iwr; - CLI R2; SSYNC; IDLE; STI R2; R0 = IWR_DISABLE_ALL; - R1 = IWR_DISABLE_ALL; - call _set_sicb_iwr; + P0.H = hi(SYSMMR_BASE); + P0.L = lo(SYSMMR_BASE); + [P0 + (SICB_IWR0 - SYSMMR_BASE)] = R0; + [P0 + (SICB_IWR1 - SYSMMR_BASE)] = R0; + SSYNC; p0.h = hi(COREB_L1_CODE_START); p0.l = lo(COREB_L1_CODE_START); jump (p0); -ENDPROC(_coreb_sleep) +ENDPROC(_coreb_die) +#endif -__CPUINIT +__INIT ENTRY(_coreb_start) [--sp] = reti; diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c index 1074a7ef81c..7b07740cf68 100644 --- a/arch/blackfin/mach-bf561/smp.c +++ b/arch/blackfin/mach-bf561/smp.c @@ -30,18 +30,11 @@ void __init platform_init_cpus(void) 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); - - 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); } int __init setup_profiling_timer(unsigned int multiplier) /* not supported */ @@ -161,9 +154,13 @@ void platform_clear_ipi(unsigned int cpu, int irq) void __cpuinit 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); |