aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r--include/asm-powerpc/atomic.h7
-rw-r--r--include/asm-powerpc/bitops.h1
-rw-r--r--include/asm-powerpc/kdebug.h19
-rw-r--r--include/asm-powerpc/kexec.h2
-rw-r--r--include/asm-powerpc/local.h201
-rw-r--r--include/asm-powerpc/parport.h5
-rw-r--r--include/asm-powerpc/system.h130
7 files changed, 331 insertions, 34 deletions
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index 2ce4b6b7b348..c44810b9d322 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -11,6 +11,7 @@ typedef struct { volatile int counter; } atomic_t;
11#include <linux/compiler.h> 11#include <linux/compiler.h>
12#include <asm/synch.h> 12#include <asm/synch.h>
13#include <asm/asm-compat.h> 13#include <asm/asm-compat.h>
14#include <asm/system.h>
14 15
15#define ATOMIC_INIT(i) { (i) } 16#define ATOMIC_INIT(i) { (i) }
16 17
@@ -165,8 +166,7 @@ static __inline__ int atomic_dec_return(atomic_t *v)
165 return t; 166 return t;
166} 167}
167 168
168#define atomic_cmpxchg(v, o, n) \ 169#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
169 ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
170#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) 170#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
171 171
172/** 172/**
@@ -414,8 +414,7 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
414 return t; 414 return t;
415} 415}
416 416
417#define atomic64_cmpxchg(v, o, n) \ 417#define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
418 ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
419#define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) 418#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
420 419
421/** 420/**
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index 8f757f6246e4..8144a2788db6 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -39,7 +39,6 @@
39#ifdef __KERNEL__ 39#ifdef __KERNEL__
40 40
41#include <linux/compiler.h> 41#include <linux/compiler.h>
42#include <asm/atomic.h>
43#include <asm/asm-compat.h> 42#include <asm/asm-compat.h>
44#include <asm/synch.h> 43#include <asm/synch.h>
45 44
diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h
index df996b933def..295f0162c608 100644
--- a/include/asm-powerpc/kdebug.h
+++ b/include/asm-powerpc/kdebug.h
@@ -6,19 +6,6 @@
6 6
7#include <linux/notifier.h> 7#include <linux/notifier.h>
8 8
9struct pt_regs;
10
11struct die_args {
12 struct pt_regs *regs;
13 const char *str;
14 long err;
15 int trapnr;
16 int signr;
17};
18
19extern int register_die_notifier(struct notifier_block *);
20extern int unregister_die_notifier(struct notifier_block *);
21
22/* 9/*
23 * These are only here because kprobes.c wants them to implement a 10 * These are only here because kprobes.c wants them to implement a
24 * blatant layering violation. Will hopefully go away soon once all 11 * blatant layering violation. Will hopefully go away soon once all
@@ -43,11 +30,5 @@ enum die_val {
43 DIE_SSTEP, 30 DIE_SSTEP,
44}; 31};
45 32
46static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
47{
48 struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig };
49 return atomic_notifier_call_chain(&powerpc_die_chain, val, &args);
50}
51
52#endif /* __KERNEL__ */ 33#endif /* __KERNEL__ */
53#endif /* _ASM_POWERPC_KDEBUG_H */ 34#endif /* _ASM_POWERPC_KDEBUG_H */
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
index 11cbdf81fd2e..b6f817b8ba3d 100644
--- a/include/asm-powerpc/kexec.h
+++ b/include/asm-powerpc/kexec.h
@@ -108,8 +108,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
108 struct pt_regs *oldregs) { } 108 struct pt_regs *oldregs) { }
109#endif /* !__powerpc64 __ */ 109#endif /* !__powerpc64 __ */
110 110
111#define MAX_NOTE_BYTES 1024
112
113extern void kexec_smp_wait(void); /* get and clear naca physid, wait for 111extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
114 master to copy new code to 0 */ 112 master to copy new code to 0 */
115extern int crashing_cpu; 113extern int crashing_cpu;
diff --git a/include/asm-powerpc/local.h b/include/asm-powerpc/local.h
index c11c530f74d0..612d83276653 100644
--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,200 @@
1#include <asm-generic/local.h> 1#ifndef _ARCH_POWERPC_LOCAL_H
2#define _ARCH_POWERPC_LOCAL_H
3
4#include <linux/percpu.h>
5#include <asm/atomic.h>
6
7typedef struct
8{
9 atomic_long_t a;
10} local_t;
11
12#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
13
14#define local_read(l) atomic_long_read(&(l)->a)
15#define local_set(l,i) atomic_long_set(&(l)->a, (i))
16
17#define local_add(i,l) atomic_long_add((i),(&(l)->a))
18#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
19#define local_inc(l) atomic_long_inc(&(l)->a)
20#define local_dec(l) atomic_long_dec(&(l)->a)
21
22static __inline__ long local_add_return(long a, local_t *l)
23{
24 long t;
25
26 __asm__ __volatile__(
27"1:" PPC_LLARX "%0,0,%2 # local_add_return\n\
28 add %0,%1,%0\n"
29 PPC405_ERR77(0,%2)
30 PPC_STLCX "%0,0,%2 \n\
31 bne- 1b"
32 : "=&r" (t)
33 : "r" (a), "r" (&(l->a.counter))
34 : "cc", "memory");
35
36 return t;
37}
38
39#define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
40
41static __inline__ long local_sub_return(long a, local_t *l)
42{
43 long t;
44
45 __asm__ __volatile__(
46"1:" PPC_LLARX "%0,0,%2 # local_sub_return\n\
47 subf %0,%1,%0\n"
48 PPC405_ERR77(0,%2)
49 PPC_STLCX "%0,0,%2 \n\
50 bne- 1b"
51 : "=&r" (t)
52 : "r" (a), "r" (&(l->a.counter))
53 : "cc", "memory");
54
55 return t;
56}
57
58static __inline__ long local_inc_return(local_t *l)
59{
60 long t;
61
62 __asm__ __volatile__(
63"1:" PPC_LLARX "%0,0,%1 # local_inc_return\n\
64 addic %0,%0,1\n"
65 PPC405_ERR77(0,%1)
66 PPC_STLCX "%0,0,%1 \n\
67 bne- 1b"
68 : "=&r" (t)
69 : "r" (&(l->a.counter))
70 : "cc", "memory");
71
72 return t;
73}
74
75/*
76 * local_inc_and_test - increment and test
77 * @l: pointer of type local_t
78 *
79 * Atomically increments @l by 1
80 * and returns true if the result is zero, or false for all
81 * other cases.
82 */
83#define local_inc_and_test(l) (local_inc_return(l) == 0)
84
85static __inline__ long local_dec_return(local_t *l)
86{
87 long t;
88
89 __asm__ __volatile__(
90"1:" PPC_LLARX "%0,0,%1 # local_dec_return\n\
91 addic %0,%0,-1\n"
92 PPC405_ERR77(0,%1)
93 PPC_STLCX "%0,0,%1\n\
94 bne- 1b"
95 : "=&r" (t)
96 : "r" (&(l->a.counter))
97 : "cc", "memory");
98
99 return t;
100}
101
102#define local_cmpxchg(l, o, n) \
103 (cmpxchg_local(&((l)->a.counter), (o), (n)))
104#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
105
106/**
107 * local_add_unless - add unless the number is a given value
108 * @l: pointer of type local_t
109 * @a: the amount to add to v...
110 * @u: ...unless v is equal to u.
111 *
112 * Atomically adds @a to @l, so long as it was not @u.
113 * Returns non-zero if @l was not @u, and zero otherwise.
114 */
115static __inline__ int local_add_unless(local_t *l, long a, long u)
116{
117 long t;
118
119 __asm__ __volatile__ (
120"1:" PPC_LLARX "%0,0,%1 # local_add_unless\n\
121 cmpw 0,%0,%3 \n\
122 beq- 2f \n\
123 add %0,%2,%0 \n"
124 PPC405_ERR77(0,%2)
125 PPC_STLCX "%0,0,%1 \n\
126 bne- 1b \n"
127" subf %0,%2,%0 \n\
1282:"
129 : "=&r" (t)
130 : "r" (&(l->a.counter)), "r" (a), "r" (u)
131 : "cc", "memory");
132
133 return t != u;
134}
135
136#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
137
138#define local_sub_and_test(a, l) (local_sub_return((a), (l)) == 0)
139#define local_dec_and_test(l) (local_dec_return((l)) == 0)
140
141/*
142 * Atomically test *l and decrement if it is greater than 0.
143 * The function returns the old value of *l minus 1.
144 */
145static __inline__ long local_dec_if_positive(local_t *l)
146{
147 long t;
148
149 __asm__ __volatile__(
150"1:" PPC_LLARX "%0,0,%1 # local_dec_if_positive\n\
151 cmpwi %0,1\n\
152 addi %0,%0,-1\n\
153 blt- 2f\n"
154 PPC405_ERR77(0,%1)
155 PPC_STLCX "%0,0,%1\n\
156 bne- 1b"
157 "\n\
1582:" : "=&b" (t)
159 : "r" (&(l->a.counter))
160 : "cc", "memory");
161
162 return t;
163}
164
165/* Use these for per-cpu local_t variables: on some archs they are
166 * much more efficient than these naive implementations. Note they take
167 * a variable, not an address.
168 */
169
170#define __local_inc(l) ((l)->a.counter++)
171#define __local_dec(l) ((l)->a.counter++)
172#define __local_add(i,l) ((l)->a.counter+=(i))
173#define __local_sub(i,l) ((l)->a.counter-=(i))
174
175/* Need to disable preemption for the cpu local counters otherwise we could
176 still access a variable of a previous CPU in a non atomic way. */
177#define cpu_local_wrap_v(l) \
178 ({ local_t res__; \
179 preempt_disable(); \
180 res__ = (l); \
181 preempt_enable(); \
182 res__; })
183#define cpu_local_wrap(l) \
184 ({ preempt_disable(); \
185 l; \
186 preempt_enable(); }) \
187
188#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
189#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
190#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
191#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
192#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
193#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
194
195#define __cpu_local_inc(l) cpu_local_inc(l)
196#define __cpu_local_dec(l) cpu_local_dec(l)
197#define __cpu_local_add(i, l) cpu_local_add((i), (l))
198#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
199
200#endif /* _ARCH_POWERPC_LOCAL_H */
diff --git a/include/asm-powerpc/parport.h b/include/asm-powerpc/parport.h
index b37b81e37278..414c50e2e881 100644
--- a/include/asm-powerpc/parport.h
+++ b/include/asm-powerpc/parport.h
@@ -12,11 +12,6 @@
12 12
13#include <asm/prom.h> 13#include <asm/prom.h>
14 14
15extern struct parport *parport_pc_probe_port (unsigned long int base,
16 unsigned long int base_hi,
17 int irq, int dma,
18 struct pci_dev *dev);
19
20static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) 15static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
21{ 16{
22 struct device_node *np; 17 struct device_node *np;
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index d3e0906ff2bc..09621f611dbc 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -7,7 +7,6 @@
7#include <linux/kernel.h> 7#include <linux/kernel.h>
8 8
9#include <asm/hw_irq.h> 9#include <asm/hw_irq.h>
10#include <asm/atomic.h>
11 10
12/* 11/*
13 * Memory barrier. 12 * Memory barrier.
@@ -227,6 +226,29 @@ __xchg_u32(volatile void *p, unsigned long val)
227 return prev; 226 return prev;
228} 227}
229 228
229/*
230 * Atomic exchange
231 *
232 * Changes the memory location '*ptr' to be val and returns
233 * the previous value stored there.
234 */
235static __inline__ unsigned long
236__xchg_u32_local(volatile void *p, unsigned long val)
237{
238 unsigned long prev;
239
240 __asm__ __volatile__(
241"1: lwarx %0,0,%2 \n"
242 PPC405_ERR77(0,%2)
243" stwcx. %3,0,%2 \n\
244 bne- 1b"
245 : "=&r" (prev), "+m" (*(volatile unsigned int *)p)
246 : "r" (p), "r" (val)
247 : "cc", "memory");
248
249 return prev;
250}
251
230#ifdef CONFIG_PPC64 252#ifdef CONFIG_PPC64
231static __inline__ unsigned long 253static __inline__ unsigned long
232__xchg_u64(volatile void *p, unsigned long val) 254__xchg_u64(volatile void *p, unsigned long val)
@@ -246,6 +268,23 @@ __xchg_u64(volatile void *p, unsigned long val)
246 268
247 return prev; 269 return prev;
248} 270}
271
272static __inline__ unsigned long
273__xchg_u64_local(volatile void *p, unsigned long val)
274{
275 unsigned long prev;
276
277 __asm__ __volatile__(
278"1: ldarx %0,0,%2 \n"
279 PPC405_ERR77(0,%2)
280" stdcx. %3,0,%2 \n\
281 bne- 1b"
282 : "=&r" (prev), "+m" (*(volatile unsigned long *)p)
283 : "r" (p), "r" (val)
284 : "cc", "memory");
285
286 return prev;
287}
249#endif 288#endif
250 289
251/* 290/*
@@ -269,13 +308,32 @@ __xchg(volatile void *ptr, unsigned long x, unsigned int size)
269 return x; 308 return x;
270} 309}
271 310
311static __inline__ unsigned long
312__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
313{
314 switch (size) {
315 case 4:
316 return __xchg_u32_local(ptr, x);
317#ifdef CONFIG_PPC64
318 case 8:
319 return __xchg_u64_local(ptr, x);
320#endif
321 }
322 __xchg_called_with_bad_pointer();
323 return x;
324}
272#define xchg(ptr,x) \ 325#define xchg(ptr,x) \
273 ({ \ 326 ({ \
274 __typeof__(*(ptr)) _x_ = (x); \ 327 __typeof__(*(ptr)) _x_ = (x); \
275 (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \ 328 (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
276 }) 329 })
277 330
278#define tas(ptr) (xchg((ptr),1)) 331#define xchg_local(ptr,x) \
332 ({ \
333 __typeof__(*(ptr)) _x_ = (x); \
334 (__typeof__(*(ptr))) __xchg_local((ptr), \
335 (unsigned long)_x_, sizeof(*(ptr))); \
336 })
279 337
280/* 338/*
281 * Compare and exchange - if *p == old, set it to new, 339 * Compare and exchange - if *p == old, set it to new,
@@ -306,6 +364,28 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
306 return prev; 364 return prev;
307} 365}
308 366
367static __inline__ unsigned long
368__cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
369 unsigned long new)
370{
371 unsigned int prev;
372
373 __asm__ __volatile__ (
374"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
375 cmpw 0,%0,%3\n\
376 bne- 2f\n"
377 PPC405_ERR77(0,%2)
378" stwcx. %4,0,%2\n\
379 bne- 1b"
380 "\n\
3812:"
382 : "=&r" (prev), "+m" (*p)
383 : "r" (p), "r" (old), "r" (new)
384 : "cc", "memory");
385
386 return prev;
387}
388
309#ifdef CONFIG_PPC64 389#ifdef CONFIG_PPC64
310static __inline__ unsigned long 390static __inline__ unsigned long
311__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new) 391__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
@@ -328,6 +408,27 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
328 408
329 return prev; 409 return prev;
330} 410}
411
412static __inline__ unsigned long
413__cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
414 unsigned long new)
415{
416 unsigned long prev;
417
418 __asm__ __volatile__ (
419"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
420 cmpd 0,%0,%3\n\
421 bne- 2f\n\
422 stdcx. %4,0,%2\n\
423 bne- 1b"
424 "\n\
4252:"
426 : "=&r" (prev), "+m" (*p)
427 : "r" (p), "r" (old), "r" (new)
428 : "cc", "memory");
429
430 return prev;
431}
331#endif 432#endif
332 433
333/* This function doesn't exist, so you'll get a linker error 434/* This function doesn't exist, so you'll get a linker error
@@ -350,6 +451,22 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
350 return old; 451 return old;
351} 452}
352 453
454static __inline__ unsigned long
455__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
456 unsigned int size)
457{
458 switch (size) {
459 case 4:
460 return __cmpxchg_u32_local(ptr, old, new);
461#ifdef CONFIG_PPC64
462 case 8:
463 return __cmpxchg_u64_local(ptr, old, new);
464#endif
465 }
466 __cmpxchg_called_with_bad_pointer();
467 return old;
468}
469
353#define cmpxchg(ptr,o,n) \ 470#define cmpxchg(ptr,o,n) \
354 ({ \ 471 ({ \
355 __typeof__(*(ptr)) _o_ = (o); \ 472 __typeof__(*(ptr)) _o_ = (o); \
@@ -358,6 +475,15 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
358 (unsigned long)_n_, sizeof(*(ptr))); \ 475 (unsigned long)_n_, sizeof(*(ptr))); \
359 }) 476 })
360 477
478
479#define cmpxchg_local(ptr,o,n) \
480 ({ \
481 __typeof__(*(ptr)) _o_ = (o); \
482 __typeof__(*(ptr)) _n_ = (n); \
483 (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
484 (unsigned long)_n_, sizeof(*(ptr))); \
485 })
486
361#ifdef CONFIG_PPC64 487#ifdef CONFIG_PPC64
362/* 488/*
363 * We handle most unaligned accesses in hardware. On the other hand 489 * We handle most unaligned accesses in hardware. On the other hand