aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-04-14 22:03:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-04-14 22:03:27 -0400
commite38f5b745075828ac51b12c8c95c85a7be4a3ec7 (patch)
tree603387de83d221f62be764de28a841ef84105413
parente6d28318344535331d9473548b210dd267fe7b7e (diff)
parent8d50de9ee77b38a239dc5b1d6a63ad92a78f119d (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vapier/blackfin
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vapier/blackfin: Blackfin: SMP: fix cache flush loop Blackfin: time-ts: ack gptimer sooner to avoid missing short ints Blackfin: gptimers: fix thinko when disabling timers Blackfin: SMP: make all barriers handle cache issues
-rw-r--r--arch/blackfin/include/asm/system.h36
-rw-r--r--arch/blackfin/kernel/gptimers.c2
-rw-r--r--arch/blackfin/kernel/time-ts.c8
-rw-r--r--arch/blackfin/mach-common/smp.c19
4 files changed, 42 insertions, 23 deletions
diff --git a/arch/blackfin/include/asm/system.h b/arch/blackfin/include/asm/system.h
index 19e2c7c3e63a..44bd0cced725 100644
--- a/arch/blackfin/include/asm/system.h
+++ b/arch/blackfin/include/asm/system.h
@@ -19,11 +19,11 @@
19 * Force strict CPU ordering. 19 * Force strict CPU ordering.
20 */ 20 */
21#define nop() __asm__ __volatile__ ("nop;\n\t" : : ) 21#define nop() __asm__ __volatile__ ("nop;\n\t" : : )
22#define mb() __asm__ __volatile__ ("" : : : "memory") 22#define smp_mb() mb()
23#define rmb() __asm__ __volatile__ ("" : : : "memory") 23#define smp_rmb() rmb()
24#define wmb() __asm__ __volatile__ ("" : : : "memory") 24#define smp_wmb() wmb()
25#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) 25#define set_mb(var, value) do { var = value; mb(); } while (0)
26#define read_barrier_depends() do { } while(0) 26#define smp_read_barrier_depends() read_barrier_depends()
27 27
28#ifdef CONFIG_SMP 28#ifdef CONFIG_SMP
29asmlinkage unsigned long __raw_xchg_1_asm(volatile void *ptr, unsigned long value); 29asmlinkage unsigned long __raw_xchg_1_asm(volatile void *ptr, unsigned long value);
@@ -37,16 +37,16 @@ asmlinkage unsigned long __raw_cmpxchg_4_asm(volatile void *ptr,
37 unsigned long new, unsigned long old); 37 unsigned long new, unsigned long old);
38 38
39#ifdef __ARCH_SYNC_CORE_DCACHE 39#ifdef __ARCH_SYNC_CORE_DCACHE
40# define smp_mb() do { barrier(); smp_check_barrier(); smp_mark_barrier(); } while (0) 40/* Force Core data cache coherence */
41# define smp_rmb() do { barrier(); smp_check_barrier(); } while (0) 41# define mb() do { barrier(); smp_check_barrier(); smp_mark_barrier(); } while (0)
42# define smp_wmb() do { barrier(); smp_mark_barrier(); } while (0) 42# define rmb() do { barrier(); smp_check_barrier(); } while (0)
43#define smp_read_barrier_depends() do { barrier(); smp_check_barrier(); } while (0) 43# define wmb() do { barrier(); smp_mark_barrier(); } while (0)
44 44# define read_barrier_depends() do { barrier(); smp_check_barrier(); } while (0)
45#else 45#else
46# define smp_mb() barrier() 46# define mb() barrier()
47# define smp_rmb() barrier() 47# define rmb() barrier()
48# define smp_wmb() barrier() 48# define wmb() barrier()
49#define smp_read_barrier_depends() barrier() 49# define read_barrier_depends() do { } while (0)
50#endif 50#endif
51 51
52static inline unsigned long __xchg(unsigned long x, volatile void *ptr, 52static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
@@ -99,10 +99,10 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
99 99
100#else /* !CONFIG_SMP */ 100#else /* !CONFIG_SMP */
101 101
102#define smp_mb() barrier() 102#define mb() barrier()
103#define smp_rmb() barrier() 103#define rmb() barrier()
104#define smp_wmb() barrier() 104#define wmb() barrier()
105#define smp_read_barrier_depends() do { } while(0) 105#define read_barrier_depends() do { } while (0)
106 106
107struct __xchg_dummy { 107struct __xchg_dummy {
108 unsigned long a[100]; 108 unsigned long a[100];
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c
index cdbe075de1dc..8b81dc04488a 100644
--- a/arch/blackfin/kernel/gptimers.c
+++ b/arch/blackfin/kernel/gptimers.c
@@ -268,7 +268,7 @@ void disable_gptimers(uint16_t mask)
268 _disable_gptimers(mask); 268 _disable_gptimers(mask);
269 for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i) 269 for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i)
270 if (mask & (1 << i)) 270 if (mask & (1 << i))
271 group_regs[BFIN_TIMER_OCTET(i)]->status |= trun_mask[i]; 271 group_regs[BFIN_TIMER_OCTET(i)]->status = trun_mask[i];
272 SSYNC(); 272 SSYNC();
273} 273}
274EXPORT_SYMBOL(disable_gptimers); 274EXPORT_SYMBOL(disable_gptimers);
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index 8c9a43daf80f..cdb4beb6bc8f 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -206,8 +206,14 @@ irqreturn_t bfin_gptmr0_interrupt(int irq, void *dev_id)
206{ 206{
207 struct clock_event_device *evt = dev_id; 207 struct clock_event_device *evt = dev_id;
208 smp_mb(); 208 smp_mb();
209 evt->event_handler(evt); 209 /*
210 * We want to ACK before we handle so that we can handle smaller timer
211 * intervals. This way if the timer expires again while we're handling
212 * things, we're more likely to see that 2nd int rather than swallowing
213 * it by ACKing the int at the end of this handler.
214 */
210 bfin_gptmr0_ack(); 215 bfin_gptmr0_ack();
216 evt->event_handler(evt);
211 return IRQ_HANDLED; 217 return IRQ_HANDLED;
212} 218}
213 219
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 6e17a265c4d3..8bce5ed031e4 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -109,10 +109,23 @@ static void ipi_flush_icache(void *info)
109 struct blackfin_flush_data *fdata = info; 109 struct blackfin_flush_data *fdata = info;
110 110
111 /* Invalidate the memory holding the bounds of the flushed region. */ 111 /* Invalidate the memory holding the bounds of the flushed region. */
112 invalidate_dcache_range((unsigned long)fdata, 112 blackfin_dcache_invalidate_range((unsigned long)fdata,
113 (unsigned long)fdata + sizeof(*fdata)); 113 (unsigned long)fdata + sizeof(*fdata));
114
115 /* Make sure all write buffers in the data side of the core
116 * are flushed before trying to invalidate the icache. This
117 * needs to be after the data flush and before the icache
118 * flush so that the SSYNC does the right thing in preventing
119 * the instruction prefetcher from hitting things in cached
120 * memory at the wrong time -- it runs much further ahead than
121 * the pipeline.
122 */
123 SSYNC();
114 124
115 flush_icache_range(fdata->start, fdata->end); 125 /* ipi_flaush_icache is invoked by generic flush_icache_range,
126 * so call blackfin arch icache flush directly here.
127 */
128 blackfin_icache_flush_range(fdata->start, fdata->end);
116} 129}
117 130
118static void ipi_call_function(unsigned int cpu, struct ipi_message *msg) 131static void ipi_call_function(unsigned int cpu, struct ipi_message *msg)