diff options
author | Michal Marek <mmarek@suse.cz> | 2011-06-07 15:37:51 +0200 |
---|---|---|
committer | Michal Marek <mmarek@suse.cz> | 2011-06-07 15:37:51 +0200 |
commit | 2e483528cebad089d0bb3f9aebb0ada22d968ffa (patch) | |
tree | d701405826b271e819a9a8500838cebd37b1364a /arch/blackfin/mach-common/smp.c | |
parent | 163d3fe6a2357aba7b18b938d6ae6ce9570324e4 (diff) | |
parent | 55922c9d1b84b89cb946c777fddccb3247e7df2c (diff) |
Merge commit 'v3.0-rc1' into kbuild/kbuild
Diffstat (limited to 'arch/blackfin/mach-common/smp.c')
-rw-r--r-- | arch/blackfin/mach-common/smp.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 6e17a265c4d..35e7e1eb018 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -25,6 +25,7 @@ #include <linux/slab.h> #include <asm/atomic.h> #include <asm/cacheflush.h> +#include <asm/irq_handler.h> #include <asm/mmu_context.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> @@ -96,7 +97,7 @@ static void ipi_cpu_stop(unsigned int cpu) dump_stack(); spin_unlock(&stop_lock); - cpu_clear(cpu, cpu_online_map); + set_cpu_online(cpu, false); local_irq_disable(); @@ -109,10 +110,23 @@ static void ipi_flush_icache(void *info) struct blackfin_flush_data *fdata = info; /* Invalidate the memory holding the bounds of the flushed region. */ - invalidate_dcache_range((unsigned long)fdata, - (unsigned long)fdata + sizeof(*fdata)); + blackfin_dcache_invalidate_range((unsigned long)fdata, + (unsigned long)fdata + sizeof(*fdata)); + + /* Make sure all write buffers in the data side of the core + * are flushed before trying to invalidate the icache. This + * needs to be after the data flush and before the icache + * flush so that the SSYNC does the right thing in preventing + * the instruction prefetcher from hitting things in cached + * memory at the wrong time -- it runs much further ahead than + * the pipeline. + */ + SSYNC(); - flush_icache_range(fdata->start, fdata->end); + /* ipi_flaush_icache is invoked by generic flush_icache_range, + * so call blackfin arch icache flush directly here. + */ + blackfin_icache_flush_range(fdata->start, fdata->end); } static void ipi_call_function(unsigned int cpu, struct ipi_message *msg) @@ -133,7 +147,7 @@ static void ipi_call_function(unsigned int cpu, struct ipi_message *msg) */ resync_core_dcache(); #endif - cpu_clear(cpu, *msg->call_struct.waitmask); + cpumask_clear_cpu(cpu, msg->call_struct.waitmask); } } @@ -164,6 +178,9 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) while (msg_queue->count) { msg = &msg_queue->ipi_message[msg_queue->head]; switch (msg->type) { + case BFIN_IPI_RESCHEDULE: + scheduler_ipi(); + break; case BFIN_IPI_CALL_FUNC: spin_unlock_irqrestore(&msg_queue->lock, flags); ipi_call_function(cpu, msg); @@ -206,9 +223,10 @@ static inline void smp_send_message(cpumask_t callmap, unsigned long type, struct ipi_message_queue *msg_queue; struct ipi_message *msg; unsigned long flags, next_msg; - cpumask_t waitmask = callmap; /* waitmask is shared by all cpus */ + cpumask_t waitmask; /* waitmask is shared by all cpus */ - for_each_cpu_mask(cpu, callmap) { + cpumask_copy(&waitmask, &callmap); + for_each_cpu(cpu, &callmap) { msg_queue = &per_cpu(ipi_msg_queue, cpu); spin_lock_irqsave(&msg_queue->lock, flags); if (msg_queue->count < BFIN_IPI_MSGQ_LEN) { @@ -230,7 +248,7 @@ static inline void smp_send_message(cpumask_t callmap, unsigned long type, } if (wait) { - while (!cpus_empty(waitmask)) + while (!cpumask_empty(&waitmask)) blackfin_dcache_invalidate_range( (unsigned long)(&waitmask), (unsigned long)(&waitmask)); @@ -249,9 +267,9 @@ int smp_call_function(void (*func)(void *info), void *info, int wait) cpumask_t callmap; preempt_disable(); - callmap = cpu_online_map; - cpu_clear(smp_processor_id(), callmap); - if (!cpus_empty(callmap)) + cpumask_copy(&callmap, cpu_online_mask); + cpumask_clear_cpu(smp_processor_id(), &callmap); + if (!cpumask_empty(&callmap)) smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait); preempt_enable(); @@ -268,8 +286,8 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, if (cpu_is_offline(cpu)) return 0; - cpus_clear(callmap); - cpu_set(cpu, callmap); + cpumask_clear(&callmap); + cpumask_set_cpu(cpu, &callmap); smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait); @@ -292,9 +310,9 @@ void smp_send_stop(void) cpumask_t callmap; preempt_disable(); - callmap = cpu_online_map; - cpu_clear(smp_processor_id(), callmap); - if (!cpus_empty(callmap)) + cpumask_copy(&callmap, cpu_online_mask); + cpumask_clear_cpu(smp_processor_id(), &callmap); + if (!cpumask_empty(&callmap)) smp_send_message(callmap, BFIN_IPI_CPU_STOP, NULL, NULL, 0); preempt_enable(); |