diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-13 19:12:23 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-13 19:12:23 -0500 |
| commit | 463020ce428e2f00d4f33a383d6f39c7453a6854 (patch) | |
| tree | c82d90c19e83c32b01c9748b4671640a670324e6 /include | |
| parent | 58a3bb59973e33a428d72fa530a3d1d81feb0e8f (diff) | |
| parent | 431dc8040354db65e4f8d4d4e21ae4fab41f5bc3 (diff) | |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus:
[MIPS] Fix sigset_t endianess swapping issues in 32-bit compat code.
[MIPS] Fix uniprocessor Sibyte builds.
[MIPS] Make entry.S a little more readable.
[MIPS] Remove stray instruction from __get_user_asm_ll32.
[MIPS] 32-bit: Fix warning about cast for fetching pointer from userspace.
[MIPS] DECstation: Fix irq handling
[MIPS] signals: make common _BLOCKABLE macro
[MIPS] signal: Move sigframe definition for native O32/N64 into signal.c
[MIPS] signal: Move {restore,setup}_sigcontext prototypes to their user
[MIPS] signal: Fix warnings in o32 compat code.
[MIPS] IP27: Enable N32 support in defconfig.
Revert "[MIPS] Fix warning in get_user when fetching pointer object from userspace."
[MIPS] Don't claim we support dma_declare_coherent_memory - we don't.
[MIPS] Unify dma-{coherent,noncoherent.ip27,ip32}
[MIPS] Improve branch prediction in ll/sc atomic operations.
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-mips/atomic.h | 50 | ||||
| -rw-r--r-- | include/asm-mips/bitops.h | 33 | ||||
| -rw-r--r-- | include/asm-mips/compat-signal.h | 55 | ||||
| -rw-r--r-- | include/asm-mips/dma-mapping.h | 2 | ||||
| -rw-r--r-- | include/asm-mips/mach-generic/dma-coherence.h | 43 | ||||
| -rw-r--r-- | include/asm-mips/mach-generic/kmalloc.h | 1 | ||||
| -rw-r--r-- | include/asm-mips/mach-ip27/dma-coherence.h | 49 | ||||
| -rw-r--r-- | include/asm-mips/mach-ip32/dma-coherence.h | 71 | ||||
| -rw-r--r-- | include/asm-mips/mach-jazz/dma-coherence.h | 40 | ||||
| -rw-r--r-- | include/asm-mips/spinlock.h | 56 | ||||
| -rw-r--r-- | include/asm-mips/system.h | 20 | ||||
| -rw-r--r-- | include/asm-mips/uaccess.h | 10 |
12 files changed, 396 insertions, 34 deletions
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index c1a2409bb52a..8578869a8bcf 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h | |||
| @@ -69,7 +69,10 @@ static __inline__ void atomic_add(int i, atomic_t * v) | |||
| 69 | "1: ll %0, %1 # atomic_add \n" | 69 | "1: ll %0, %1 # atomic_add \n" |
| 70 | " addu %0, %2 \n" | 70 | " addu %0, %2 \n" |
| 71 | " sc %0, %1 \n" | 71 | " sc %0, %1 \n" |
| 72 | " beqz %0, 1b \n" | 72 | " beqz %0, 2f \n" |
| 73 | " .subsection 2 \n" | ||
| 74 | "2: b 1b \n" | ||
| 75 | " .previous \n" | ||
| 73 | " .set mips0 \n" | 76 | " .set mips0 \n" |
| 74 | : "=&r" (temp), "=m" (v->counter) | 77 | : "=&r" (temp), "=m" (v->counter) |
| 75 | : "Ir" (i), "m" (v->counter)); | 78 | : "Ir" (i), "m" (v->counter)); |
| @@ -111,7 +114,10 @@ static __inline__ void atomic_sub(int i, atomic_t * v) | |||
| 111 | "1: ll %0, %1 # atomic_sub \n" | 114 | "1: ll %0, %1 # atomic_sub \n" |
| 112 | " subu %0, %2 \n" | 115 | " subu %0, %2 \n" |
| 113 | " sc %0, %1 \n" | 116 | " sc %0, %1 \n" |
| 114 | " beqz %0, 1b \n" | 117 | " beqz %0, 2f \n" |
| 118 | " .subsection 2 \n" | ||
| 119 | "2: b 1b \n" | ||
| 120 | " .previous \n" | ||
| 115 | " .set mips0 \n" | 121 | " .set mips0 \n" |
| 116 | : "=&r" (temp), "=m" (v->counter) | 122 | : "=&r" (temp), "=m" (v->counter) |
| 117 | : "Ir" (i), "m" (v->counter)); | 123 | : "Ir" (i), "m" (v->counter)); |
| @@ -155,8 +161,11 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) | |||
| 155 | "1: ll %1, %2 # atomic_add_return \n" | 161 | "1: ll %1, %2 # atomic_add_return \n" |
| 156 | " addu %0, %1, %3 \n" | 162 | " addu %0, %1, %3 \n" |
| 157 | " sc %0, %2 \n" | 163 | " sc %0, %2 \n" |
| 158 | " beqz %0, 1b \n" | 164 | " beqz %0, 2f \n" |
| 159 | " addu %0, %1, %3 \n" | 165 | " addu %0, %1, %3 \n" |
| 166 | " .subsection 2 \n" | ||
| 167 | "2: b 1b \n" | ||
| 168 | " .previous \n" | ||
| 160 | " .set mips0 \n" | 169 | " .set mips0 \n" |
| 161 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 170 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
| 162 | : "Ir" (i), "m" (v->counter) | 171 | : "Ir" (i), "m" (v->counter) |
| @@ -204,8 +213,11 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) | |||
| 204 | "1: ll %1, %2 # atomic_sub_return \n" | 213 | "1: ll %1, %2 # atomic_sub_return \n" |
| 205 | " subu %0, %1, %3 \n" | 214 | " subu %0, %1, %3 \n" |
| 206 | " sc %0, %2 \n" | 215 | " sc %0, %2 \n" |
| 207 | " beqz %0, 1b \n" | 216 | " beqz %0, 2f \n" |
| 208 | " subu %0, %1, %3 \n" | 217 | " subu %0, %1, %3 \n" |
| 218 | " .subsection 2 \n" | ||
| 219 | "2: b 1b \n" | ||
| 220 | " .previous \n" | ||
| 209 | " .set mips0 \n" | 221 | " .set mips0 \n" |
| 210 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 222 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
| 211 | : "Ir" (i), "m" (v->counter) | 223 | : "Ir" (i), "m" (v->counter) |
| @@ -267,10 +279,13 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
| 267 | " bltz %0, 1f \n" | 279 | " bltz %0, 1f \n" |
| 268 | " sc %0, %2 \n" | 280 | " sc %0, %2 \n" |
| 269 | " .set noreorder \n" | 281 | " .set noreorder \n" |
| 270 | " beqz %0, 1b \n" | 282 | " beqz %0, 2f \n" |
| 271 | " subu %0, %1, %3 \n" | 283 | " subu %0, %1, %3 \n" |
| 272 | " .set reorder \n" | 284 | " .set reorder \n" |
| 273 | "1: \n" | 285 | "1: \n" |
| 286 | " .subsection 2 \n" | ||
| 287 | "2: b 1b \n" | ||
| 288 | " .previous \n" | ||
| 274 | " .set mips0 \n" | 289 | " .set mips0 \n" |
| 275 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 290 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
| 276 | : "Ir" (i), "m" (v->counter) | 291 | : "Ir" (i), "m" (v->counter) |
| @@ -429,7 +444,10 @@ static __inline__ void atomic64_add(long i, atomic64_t * v) | |||
| 429 | "1: lld %0, %1 # atomic64_add \n" | 444 | "1: lld %0, %1 # atomic64_add \n" |
| 430 | " addu %0, %2 \n" | 445 | " addu %0, %2 \n" |
| 431 | " scd %0, %1 \n" | 446 | " scd %0, %1 \n" |
| 432 | " beqz %0, 1b \n" | 447 | " beqz %0, 2f \n" |
| 448 | " .subsection 2 \n" | ||
| 449 | "2: b 1b \n" | ||
| 450 | " .previous \n" | ||
| 433 | " .set mips0 \n" | 451 | " .set mips0 \n" |
| 434 | : "=&r" (temp), "=m" (v->counter) | 452 | : "=&r" (temp), "=m" (v->counter) |
| 435 | : "Ir" (i), "m" (v->counter)); | 453 | : "Ir" (i), "m" (v->counter)); |
| @@ -471,7 +489,10 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v) | |||
| 471 | "1: lld %0, %1 # atomic64_sub \n" | 489 | "1: lld %0, %1 # atomic64_sub \n" |
| 472 | " subu %0, %2 \n" | 490 | " subu %0, %2 \n" |
| 473 | " scd %0, %1 \n" | 491 | " scd %0, %1 \n" |
| 474 | " beqz %0, 1b \n" | 492 | " beqz %0, 2f \n" |
| 493 | " .subsection 2 \n" | ||
| 494 | "2: b 1b \n" | ||
| 495 | " .previous \n" | ||
| 475 | " .set mips0 \n" | 496 | " .set mips0 \n" |
| 476 | : "=&r" (temp), "=m" (v->counter) | 497 | : "=&r" (temp), "=m" (v->counter) |
| 477 | : "Ir" (i), "m" (v->counter)); | 498 | : "Ir" (i), "m" (v->counter)); |
| @@ -515,8 +536,11 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) | |||
| 515 | "1: lld %1, %2 # atomic64_add_return \n" | 536 | "1: lld %1, %2 # atomic64_add_return \n" |
| 516 | " addu %0, %1, %3 \n" | 537 | " addu %0, %1, %3 \n" |
| 517 | " scd %0, %2 \n" | 538 | " scd %0, %2 \n" |
| 518 | " beqz %0, 1b \n" | 539 | " beqz %0, 2f \n" |
| 519 | " addu %0, %1, %3 \n" | 540 | " addu %0, %1, %3 \n" |
| 541 | " .subsection 2 \n" | ||
| 542 | "2: b 1b \n" | ||
| 543 | " .previous \n" | ||
| 520 | " .set mips0 \n" | 544 | " .set mips0 \n" |
| 521 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 545 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
| 522 | : "Ir" (i), "m" (v->counter) | 546 | : "Ir" (i), "m" (v->counter) |
| @@ -564,8 +588,11 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) | |||
| 564 | "1: lld %1, %2 # atomic64_sub_return \n" | 588 | "1: lld %1, %2 # atomic64_sub_return \n" |
| 565 | " subu %0, %1, %3 \n" | 589 | " subu %0, %1, %3 \n" |
| 566 | " scd %0, %2 \n" | 590 | " scd %0, %2 \n" |
| 567 | " beqz %0, 1b \n" | 591 | " beqz %0, 2f \n" |
| 568 | " subu %0, %1, %3 \n" | 592 | " subu %0, %1, %3 \n" |
| 593 | " .subsection 2 \n" | ||
| 594 | "2: b 1b \n" | ||
| 595 | " .previous \n" | ||
| 569 | " .set mips0 \n" | 596 | " .set mips0 \n" |
| 570 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 597 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
| 571 | : "Ir" (i), "m" (v->counter) | 598 | : "Ir" (i), "m" (v->counter) |
| @@ -627,10 +654,13 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) | |||
| 627 | " bltz %0, 1f \n" | 654 | " bltz %0, 1f \n" |
| 628 | " scd %0, %2 \n" | 655 | " scd %0, %2 \n" |
| 629 | " .set noreorder \n" | 656 | " .set noreorder \n" |
| 630 | " beqz %0, 1b \n" | 657 | " beqz %0, 2f \n" |
| 631 | " dsubu %0, %1, %3 \n" | 658 | " dsubu %0, %1, %3 \n" |
| 632 | " .set reorder \n" | 659 | " .set reorder \n" |
| 633 | "1: \n" | 660 | "1: \n" |
| 661 | " .subsection 2 \n" | ||
| 662 | "2: b 1b \n" | ||
| 663 | " .previous \n" | ||
| 634 | " .set mips0 \n" | 664 | " .set mips0 \n" |
| 635 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 665 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
| 636 | : "Ir" (i), "m" (v->counter) | 666 | : "Ir" (i), "m" (v->counter) |
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 06445de1324b..06c08228a525 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h | |||
| @@ -68,7 +68,10 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 68 | "1: " __LL "%0, %1 # set_bit \n" | 68 | "1: " __LL "%0, %1 # set_bit \n" |
| 69 | " or %0, %2 \n" | 69 | " or %0, %2 \n" |
| 70 | " " __SC "%0, %1 \n" | 70 | " " __SC "%0, %1 \n" |
| 71 | " beqz %0, 1b \n" | 71 | " beqz %0, 2f \n" |
| 72 | " .subsection 2 \n" | ||
| 73 | "2: b 1b \n" | ||
| 74 | " .previous \n" | ||
| 72 | " .set mips0 \n" | 75 | " .set mips0 \n" |
| 73 | : "=&r" (temp), "=m" (*m) | 76 | : "=&r" (temp), "=m" (*m) |
| 74 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); | 77 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); |
| @@ -116,7 +119,10 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 116 | "1: " __LL "%0, %1 # clear_bit \n" | 119 | "1: " __LL "%0, %1 # clear_bit \n" |
| 117 | " and %0, %2 \n" | 120 | " and %0, %2 \n" |
| 118 | " " __SC "%0, %1 \n" | 121 | " " __SC "%0, %1 \n" |
| 119 | " beqz %0, 1b \n" | 122 | " beqz %0, 2f \n" |
| 123 | " .subsection 2 \n" | ||
| 124 | "2: b 1b \n" | ||
| 125 | " .previous \n" | ||
| 120 | " .set mips0 \n" | 126 | " .set mips0 \n" |
| 121 | : "=&r" (temp), "=m" (*m) | 127 | : "=&r" (temp), "=m" (*m) |
| 122 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); | 128 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); |
| @@ -166,7 +172,10 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 166 | "1: " __LL "%0, %1 # change_bit \n" | 172 | "1: " __LL "%0, %1 # change_bit \n" |
| 167 | " xor %0, %2 \n" | 173 | " xor %0, %2 \n" |
| 168 | " " __SC "%0, %1 \n" | 174 | " " __SC "%0, %1 \n" |
| 169 | " beqz %0, 1b \n" | 175 | " beqz %0, 2f \n" |
| 176 | " .subsection 2 \n" | ||
| 177 | "2: b 1b \n" | ||
| 178 | " .previous \n" | ||
| 170 | " .set mips0 \n" | 179 | " .set mips0 \n" |
| 171 | : "=&r" (temp), "=m" (*m) | 180 | : "=&r" (temp), "=m" (*m) |
| 172 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); | 181 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); |
| @@ -222,8 +231,12 @@ static inline int test_and_set_bit(unsigned long nr, | |||
| 222 | "1: " __LL "%0, %1 # test_and_set_bit \n" | 231 | "1: " __LL "%0, %1 # test_and_set_bit \n" |
| 223 | " or %2, %0, %3 \n" | 232 | " or %2, %0, %3 \n" |
| 224 | " " __SC "%2, %1 \n" | 233 | " " __SC "%2, %1 \n" |
| 225 | " beqz %2, 1b \n" | 234 | " beqz %2, 2f \n" |
| 226 | " and %2, %0, %3 \n" | 235 | " and %2, %0, %3 \n" |
| 236 | " .subsection 2 \n" | ||
| 237 | "2: b 1b \n" | ||
| 238 | " nop \n" | ||
| 239 | " .previous \n" | ||
| 227 | " .set pop \n" | 240 | " .set pop \n" |
| 228 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 241 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
| 229 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 242 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
| @@ -290,8 +303,12 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 290 | " or %2, %0, %3 \n" | 303 | " or %2, %0, %3 \n" |
| 291 | " xor %2, %3 \n" | 304 | " xor %2, %3 \n" |
| 292 | " " __SC "%2, %1 \n" | 305 | " " __SC "%2, %1 \n" |
| 293 | " beqz %2, 1b \n" | 306 | " beqz %2, 2f \n" |
| 294 | " and %2, %0, %3 \n" | 307 | " and %2, %0, %3 \n" |
| 308 | " .subsection 2 \n" | ||
| 309 | "2: b 1b \n" | ||
| 310 | " nop \n" | ||
| 311 | " .previous \n" | ||
| 295 | " .set pop \n" | 312 | " .set pop \n" |
| 296 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 313 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
| 297 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 314 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
| @@ -356,8 +373,12 @@ static inline int test_and_change_bit(unsigned long nr, | |||
| 356 | "1: " __LL "%0, %1 # test_and_change_bit \n" | 373 | "1: " __LL "%0, %1 # test_and_change_bit \n" |
| 357 | " xor %2, %0, %3 \n" | 374 | " xor %2, %0, %3 \n" |
| 358 | " " __SC "\t%2, %1 \n" | 375 | " " __SC "\t%2, %1 \n" |
| 359 | " beqz %2, 1b \n" | 376 | " beqz %2, 2f \n" |
| 360 | " and %2, %0, %3 \n" | 377 | " and %2, %0, %3 \n" |
| 378 | " .subsection 2 \n" | ||
| 379 | "2: b 1b \n" | ||
| 380 | " nop \n" | ||
| 381 | " .previous \n" | ||
| 361 | " .set pop \n" | 382 | " .set pop \n" |
| 362 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 383 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
| 363 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 384 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
diff --git a/include/asm-mips/compat-signal.h b/include/asm-mips/compat-signal.h new file mode 100644 index 000000000000..672077084aa1 --- /dev/null +++ b/include/asm-mips/compat-signal.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | #ifndef __ASM_COMPAT_SIGNAL_H | ||
| 2 | #define __ASM_COMPAT_SIGNAL_H | ||
| 3 | |||
| 4 | #include <linux/bug.h> | ||
| 5 | #include <linux/compat.h> | ||
| 6 | #include <linux/compiler.h> | ||
| 7 | |||
| 8 | static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d, | ||
| 9 | const sigset_t *s) | ||
| 10 | { | ||
| 11 | int err; | ||
| 12 | |||
| 13 | BUG_ON(sizeof(*d) != sizeof(*s)); | ||
| 14 | BUG_ON(_NSIG_WORDS != 2); | ||
| 15 | |||
| 16 | err = __put_user(s->sig[0], &d->sig[0]); | ||
| 17 | err |= __put_user(s->sig[0] >> 32, &d->sig[1]); | ||
| 18 | err |= __put_user(s->sig[1], &d->sig[2]); | ||
| 19 | err |= __put_user(s->sig[1] >> 32, &d->sig[3]); | ||
| 20 | |||
| 21 | return err; | ||
| 22 | } | ||
| 23 | |||
| 24 | static inline int __copy_conv_sigset_from_user(sigset_t *d, | ||
| 25 | const compat_sigset_t __user *s) | ||
| 26 | { | ||
| 27 | int err; | ||
| 28 | union sigset_u { | ||
| 29 | sigset_t s; | ||
| 30 | compat_sigset_t c; | ||
| 31 | } *u = (union sigset_u *) d; | ||
| 32 | |||
| 33 | BUG_ON(sizeof(*d) != sizeof(*s)); | ||
| 34 | BUG_ON(_NSIG_WORDS != 2); | ||
| 35 | |||
| 36 | if (unlikely(!access_ok(VERIFY_READ, d, sizeof(*d)))) | ||
| 37 | return -EFAULT; | ||
| 38 | |||
| 39 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
| 40 | err = __get_user(u->c.sig[1], &s->sig[0]); | ||
| 41 | err |= __get_user(u->c.sig[0], &s->sig[1]); | ||
| 42 | err |= __get_user(u->c.sig[3], &s->sig[2]); | ||
| 43 | err |= __get_user(u->c.sig[2], &s->sig[3]); | ||
| 44 | #endif | ||
| 45 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
| 46 | err = __get_user(u->c.sig[0], &s->sig[0]); | ||
| 47 | err |= __get_user(u->c.sig[1], &s->sig[1]); | ||
| 48 | err |= __get_user(u->c.sig[2], &s->sig[2]); | ||
| 49 | err |= __get_user(u->c.sig[3], &s->sig[3]); | ||
| 50 | #endif | ||
| 51 | |||
| 52 | return err; | ||
| 53 | } | ||
| 54 | |||
| 55 | #endif /* __ASM_COMPAT_SIGNAL_H */ | ||
diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h index 236d1a467cc7..230b3f1b69b1 100644 --- a/include/asm-mips/dma-mapping.h +++ b/include/asm-mips/dma-mapping.h | |||
| @@ -68,6 +68,7 @@ extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr); | |||
| 68 | extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 68 | extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
| 69 | enum dma_data_direction direction); | 69 | enum dma_data_direction direction); |
| 70 | 70 | ||
| 71 | #if 0 | ||
| 71 | #define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY | 72 | #define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY |
| 72 | 73 | ||
| 73 | extern int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | 74 | extern int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, |
| @@ -75,5 +76,6 @@ extern int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | |||
| 75 | extern void dma_release_declared_memory(struct device *dev); | 76 | extern void dma_release_declared_memory(struct device *dev); |
| 76 | extern void * dma_mark_declared_memory_occupied(struct device *dev, | 77 | extern void * dma_mark_declared_memory_occupied(struct device *dev, |
| 77 | dma_addr_t device_addr, size_t size); | 78 | dma_addr_t device_addr, size_t size); |
| 79 | #endif | ||
| 78 | 80 | ||
| 79 | #endif /* _ASM_DMA_MAPPING_H */ | 81 | #endif /* _ASM_DMA_MAPPING_H */ |
diff --git a/include/asm-mips/mach-generic/dma-coherence.h b/include/asm-mips/mach-generic/dma-coherence.h new file mode 100644 index 000000000000..df71822fd27b --- /dev/null +++ b/include/asm-mips/mach-generic/dma-coherence.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||
| 7 | * | ||
| 8 | */ | ||
| 9 | #ifndef __ASM_MACH_GENERIC_DMA_COHERENCE_H | ||
| 10 | #define __ASM_MACH_GENERIC_DMA_COHERENCE_H | ||
| 11 | |||
| 12 | struct device; | ||
| 13 | |||
| 14 | static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||
| 15 | { | ||
| 16 | return virt_to_phys(addr); | ||
| 17 | } | ||
| 18 | |||
| 19 | static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) | ||
| 20 | { | ||
| 21 | return page_to_phys(page); | ||
| 22 | } | ||
| 23 | |||
| 24 | static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) | ||
| 25 | { | ||
| 26 | return dma_addr; | ||
| 27 | } | ||
| 28 | |||
| 29 | static void plat_unmap_dma_mem(dma_addr_t dma_addr) | ||
| 30 | { | ||
| 31 | } | ||
| 32 | |||
| 33 | static inline int plat_device_is_coherent(struct device *dev) | ||
| 34 | { | ||
| 35 | #ifdef CONFIG_DMA_COHERENT | ||
| 36 | return 1; | ||
| 37 | #endif | ||
| 38 | #ifdef CONFIG_DMA_NONCOHERENT | ||
| 39 | return 0; | ||
| 40 | #endif | ||
| 41 | } | ||
| 42 | |||
| 43 | #endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */ | ||
diff --git a/include/asm-mips/mach-generic/kmalloc.h b/include/asm-mips/mach-generic/kmalloc.h index 410ab5f6c563..b8e6deba352f 100644 --- a/include/asm-mips/mach-generic/kmalloc.h +++ b/include/asm-mips/mach-generic/kmalloc.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #ifndef CONFIG_DMA_COHERENT | 5 | #ifndef CONFIG_DMA_COHERENT |
| 6 | /* | 6 | /* |
| 7 | * Total overkill for most systems but need as a safe default. | 7 | * Total overkill for most systems but need as a safe default. |
| 8 | * Set this one if any device in the system might do non-coherent DMA. | ||
| 8 | */ | 9 | */ |
| 9 | #define ARCH_KMALLOC_MINALIGN 128 | 10 | #define ARCH_KMALLOC_MINALIGN 128 |
| 10 | #endif | 11 | #endif |
diff --git a/include/asm-mips/mach-ip27/dma-coherence.h b/include/asm-mips/mach-ip27/dma-coherence.h new file mode 100644 index 000000000000..659816e200d4 --- /dev/null +++ b/include/asm-mips/mach-ip27/dma-coherence.h | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||
| 7 | * | ||
| 8 | */ | ||
| 9 | #ifndef __ASM_MACH_IP27_DMA_COHERENCE_H | ||
| 10 | #define __ASM_MACH_IP27_DMA_COHERENCE_H | ||
| 11 | |||
| 12 | #include <asm/pci/bridge.h> | ||
| 13 | |||
| 14 | #define pdev_to_baddr(pdev, addr) \ | ||
| 15 | (BRIDGE_CONTROLLER(pdev->bus)->baddr + (addr)) | ||
| 16 | #define dev_to_baddr(dev, addr) \ | ||
| 17 | pdev_to_baddr(to_pci_dev(dev), (addr)) | ||
| 18 | |||
| 19 | struct device; | ||
| 20 | |||
| 21 | static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||
| 22 | { | ||
| 23 | dma_addr_t pa = dev_to_baddr(dev, virt_to_phys(addr)); | ||
| 24 | |||
| 25 | return pa; | ||
| 26 | } | ||
| 27 | |||
| 28 | static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) | ||
| 29 | { | ||
| 30 | dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page)); | ||
| 31 | |||
| 32 | return pa; | ||
| 33 | } | ||
| 34 | |||
| 35 | static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) | ||
| 36 | { | ||
| 37 | return dma_addr & (0xffUL << 56); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void plat_unmap_dma_mem(dma_addr_t dma_addr) | ||
| 41 | { | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline int plat_device_is_coherent(struct device *dev) | ||
| 45 | { | ||
| 46 | return 1; /* IP27 non-cohernet mode is unsupported */ | ||
| 47 | } | ||
| 48 | |||
| 49 | #endif /* __ASM_MACH_IP27_DMA_COHERENCE_H */ | ||
diff --git a/include/asm-mips/mach-ip32/dma-coherence.h b/include/asm-mips/mach-ip32/dma-coherence.h new file mode 100644 index 000000000000..950be17bbb86 --- /dev/null +++ b/include/asm-mips/mach-ip32/dma-coherence.h | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||
| 7 | * | ||
| 8 | */ | ||
| 9 | #ifndef __ASM_MACH_IP35_DMA_COHERENCE_H | ||
| 10 | #define __ASM_MACH_IP35_DMA_COHERENCE_H | ||
| 11 | |||
| 12 | #include <asm/ip32/crime.h> | ||
| 13 | |||
| 14 | struct device; | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Few notes. | ||
| 18 | * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x40000000+256M | ||
| 19 | * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x40000000 for | ||
| 20 | * native-endian) | ||
| 21 | * 3. All other devices see memory as one big chunk at 0x40000000 | ||
| 22 | * 4. Non-PCI devices will pass NULL as struct device* | ||
| 23 | * | ||
| 24 | * Thus we translate differently, depending on device. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #define RAM_OFFSET_MASK 0x3fffffffUL | ||
| 28 | |||
| 29 | static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||
| 30 | { | ||
| 31 | dma_addr_t pa = virt_to_phys(addr) & RAM_OFFSET_MASK; | ||
| 32 | |||
| 33 | if (dev == NULL) | ||
| 34 | pa += CRIME_HI_MEM_BASE; | ||
| 35 | |||
| 36 | return pa; | ||
| 37 | } | ||
| 38 | |||
| 39 | static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) | ||
| 40 | { | ||
| 41 | dma_addr_t pa; | ||
| 42 | |||
| 43 | pa = page_to_phys(page) & RAM_OFFSET_MASK; | ||
| 44 | |||
| 45 | if (dev == NULL) | ||
| 46 | pa += CRIME_HI_MEM_BASE; | ||
| 47 | |||
| 48 | return pa; | ||
| 49 | } | ||
| 50 | |||
| 51 | /* This is almost certainly wrong but it's what dma-ip32.c used to use */ | ||
| 52 | static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) | ||
| 53 | { | ||
| 54 | unsigned long addr = dma_addr & RAM_OFFSET_MASK; | ||
| 55 | |||
| 56 | if (dma_addr >= 256*1024*1024) | ||
| 57 | addr += CRIME_HI_MEM_BASE; | ||
| 58 | |||
| 59 | return addr; | ||
| 60 | } | ||
| 61 | |||
| 62 | static void plat_unmap_dma_mem(dma_addr_t dma_addr) | ||
| 63 | { | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline int plat_device_is_coherent(struct device *dev) | ||
| 67 | { | ||
| 68 | return 0; /* IP32 is non-cohernet */ | ||
| 69 | } | ||
| 70 | |||
| 71 | #endif /* __ASM_MACH_IP35_DMA_COHERENCE_H */ | ||
diff --git a/include/asm-mips/mach-jazz/dma-coherence.h b/include/asm-mips/mach-jazz/dma-coherence.h new file mode 100644 index 000000000000..d66979a124a8 --- /dev/null +++ b/include/asm-mips/mach-jazz/dma-coherence.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||
| 7 | */ | ||
| 8 | #ifndef __ASM_MACH_JAZZ_DMA_COHERENCE_H | ||
| 9 | #define __ASM_MACH_JAZZ_DMA_COHERENCE_H | ||
| 10 | |||
| 11 | #include <asm/jazzdma.h> | ||
| 12 | |||
| 13 | struct device; | ||
| 14 | |||
| 15 | static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||
| 16 | { | ||
| 17 | return vdma_alloc(virt_to_phys(addr), size); | ||
| 18 | } | ||
| 19 | |||
| 20 | static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) | ||
| 21 | { | ||
| 22 | return vdma_alloc(page_to_phys(page), PAGE_SIZE); | ||
| 23 | } | ||
| 24 | |||
| 25 | static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) | ||
| 26 | { | ||
| 27 | return vdma_log2phys(dma_addr); | ||
| 28 | } | ||
| 29 | |||
| 30 | static void plat_unmap_dma_mem(dma_addr_t dma_addr) | ||
| 31 | { | ||
| 32 | vdma_free(dma_addr); | ||
| 33 | } | ||
| 34 | |||
| 35 | static inline int plat_device_is_coherent(struct device *dev) | ||
| 36 | { | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | #endif /* __ASM_MACH_JAZZ_DMA_COHERENCE_H */ | ||
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h index fc3217fc1118..f1755d28a36a 100644 --- a/include/asm-mips/spinlock.h +++ b/include/asm-mips/spinlock.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1999, 2000, 06 by Ralf Baechle | 6 | * Copyright (C) 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org) |
| 7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
| 8 | */ | 8 | */ |
| 9 | #ifndef _ASM_SPINLOCK_H | 9 | #ifndef _ASM_SPINLOCK_H |
| @@ -49,11 +49,18 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) | |||
| 49 | __asm__ __volatile__( | 49 | __asm__ __volatile__( |
| 50 | " .set noreorder # __raw_spin_lock \n" | 50 | " .set noreorder # __raw_spin_lock \n" |
| 51 | "1: ll %1, %2 \n" | 51 | "1: ll %1, %2 \n" |
| 52 | " bnez %1, 1b \n" | 52 | " bnez %1, 2f \n" |
| 53 | " li %1, 1 \n" | 53 | " li %1, 1 \n" |
| 54 | " sc %1, %0 \n" | 54 | " sc %1, %0 \n" |
| 55 | " beqz %1, 1b \n" | 55 | " beqz %1, 2f \n" |
| 56 | " nop \n" | 56 | " nop \n" |
| 57 | " .subsection 2 \n" | ||
| 58 | "2: ll %1, %2 \n" | ||
| 59 | " bnez %1, 2b \n" | ||
| 60 | " li %1, 1 \n" | ||
| 61 | " b 1b \n" | ||
| 62 | " nop \n" | ||
| 63 | " .previous \n" | ||
| 57 | " .set reorder \n" | 64 | " .set reorder \n" |
| 58 | : "=m" (lock->lock), "=&r" (tmp) | 65 | : "=m" (lock->lock), "=&r" (tmp) |
| 59 | : "m" (lock->lock) | 66 | : "m" (lock->lock) |
| @@ -99,8 +106,12 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock) | |||
| 99 | "1: ll %0, %3 \n" | 106 | "1: ll %0, %3 \n" |
| 100 | " ori %2, %0, 1 \n" | 107 | " ori %2, %0, 1 \n" |
| 101 | " sc %2, %1 \n" | 108 | " sc %2, %1 \n" |
| 102 | " beqz %2, 1b \n" | 109 | " beqz %2, 2f \n" |
| 103 | " andi %2, %0, 1 \n" | 110 | " andi %2, %0, 1 \n" |
| 111 | " .subsection 2 \n" | ||
| 112 | "2: b 1b \n" | ||
| 113 | " nop \n" | ||
| 114 | " .previous \n" | ||
| 104 | " .set reorder" | 115 | " .set reorder" |
| 105 | : "=&r" (temp), "=m" (lock->lock), "=&r" (res) | 116 | : "=&r" (temp), "=m" (lock->lock), "=&r" (res) |
| 106 | : "m" (lock->lock) | 117 | : "m" (lock->lock) |
| @@ -154,11 +165,18 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) | |||
| 154 | __asm__ __volatile__( | 165 | __asm__ __volatile__( |
| 155 | " .set noreorder # __raw_read_lock \n" | 166 | " .set noreorder # __raw_read_lock \n" |
| 156 | "1: ll %1, %2 \n" | 167 | "1: ll %1, %2 \n" |
| 157 | " bltz %1, 1b \n" | 168 | " bltz %1, 2f \n" |
| 158 | " addu %1, 1 \n" | 169 | " addu %1, 1 \n" |
| 159 | " sc %1, %0 \n" | 170 | " sc %1, %0 \n" |
| 160 | " beqz %1, 1b \n" | 171 | " beqz %1, 1b \n" |
| 161 | " nop \n" | 172 | " nop \n" |
| 173 | " .subsection 2 \n" | ||
| 174 | "2: ll %1, %2 \n" | ||
| 175 | " bltz %1, 2b \n" | ||
| 176 | " addu %1, 1 \n" | ||
| 177 | " b 1b \n" | ||
| 178 | " nop \n" | ||
| 179 | " .previous \n" | ||
| 162 | " .set reorder \n" | 180 | " .set reorder \n" |
| 163 | : "=m" (rw->lock), "=&r" (tmp) | 181 | : "=m" (rw->lock), "=&r" (tmp) |
| 164 | : "m" (rw->lock) | 182 | : "m" (rw->lock) |
| @@ -192,8 +210,12 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) | |||
| 192 | "1: ll %1, %2 \n" | 210 | "1: ll %1, %2 \n" |
| 193 | " sub %1, 1 \n" | 211 | " sub %1, 1 \n" |
| 194 | " sc %1, %0 \n" | 212 | " sc %1, %0 \n" |
| 195 | " beqz %1, 1b \n" | 213 | " beqz %1, 2f \n" |
| 214 | " nop \n" | ||
| 215 | " .subsection 2 \n" | ||
| 216 | "2: b 1b \n" | ||
| 196 | " nop \n" | 217 | " nop \n" |
| 218 | " .previous \n" | ||
| 197 | " .set reorder \n" | 219 | " .set reorder \n" |
| 198 | : "=m" (rw->lock), "=&r" (tmp) | 220 | : "=m" (rw->lock), "=&r" (tmp) |
| 199 | : "m" (rw->lock) | 221 | : "m" (rw->lock) |
| @@ -222,11 +244,18 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) | |||
| 222 | __asm__ __volatile__( | 244 | __asm__ __volatile__( |
| 223 | " .set noreorder # __raw_write_lock \n" | 245 | " .set noreorder # __raw_write_lock \n" |
| 224 | "1: ll %1, %2 \n" | 246 | "1: ll %1, %2 \n" |
| 225 | " bnez %1, 1b \n" | 247 | " bnez %1, 2f \n" |
| 226 | " lui %1, 0x8000 \n" | 248 | " lui %1, 0x8000 \n" |
| 227 | " sc %1, %0 \n" | 249 | " sc %1, %0 \n" |
| 228 | " beqz %1, 1b \n" | 250 | " beqz %1, 2f \n" |
| 251 | " nop \n" | ||
| 252 | " .subsection 2 \n" | ||
| 253 | "2: ll %1, %2 \n" | ||
| 254 | " bnez %1, 2b \n" | ||
| 255 | " lui %1, 0x8000 \n" | ||
| 256 | " b 1b \n" | ||
| 229 | " nop \n" | 257 | " nop \n" |
| 258 | " .previous \n" | ||
| 230 | " .set reorder \n" | 259 | " .set reorder \n" |
| 231 | : "=m" (rw->lock), "=&r" (tmp) | 260 | : "=m" (rw->lock), "=&r" (tmp) |
| 232 | : "m" (rw->lock) | 261 | : "m" (rw->lock) |
| @@ -322,12 +351,15 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) | |||
| 322 | " bnez %1, 2f \n" | 351 | " bnez %1, 2f \n" |
| 323 | " lui %1, 0x8000 \n" | 352 | " lui %1, 0x8000 \n" |
| 324 | " sc %1, %0 \n" | 353 | " sc %1, %0 \n" |
| 325 | " beqz %1, 1b \n" | 354 | " beqz %1, 3f \n" |
| 326 | " nop \n" | 355 | " li %2, 1 \n" |
| 356 | "2: \n" | ||
| 327 | __WEAK_ORDERING_MB | 357 | __WEAK_ORDERING_MB |
| 328 | " li %2, 1 \n" | 358 | " .subsection 2 \n" |
| 359 | "3: b 1b \n" | ||
| 360 | " li %2, 0 \n" | ||
| 361 | " .previous \n" | ||
| 329 | " .set reorder \n" | 362 | " .set reorder \n" |
| 330 | "2: \n" | ||
| 331 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 363 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) |
| 332 | : "m" (rw->lock) | 364 | : "m" (rw->lock) |
| 333 | : "memory"); | 365 | : "memory"); |
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 5e1289c85ed9..597a3743f6a1 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h | |||
| @@ -110,7 +110,10 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | |||
| 110 | " move %2, %z4 \n" | 110 | " move %2, %z4 \n" |
| 111 | " .set mips3 \n" | 111 | " .set mips3 \n" |
| 112 | " sc %2, %1 \n" | 112 | " sc %2, %1 \n" |
| 113 | " beqz %2, 1b \n" | 113 | " beqz %2, 2f \n" |
| 114 | " .subsection 2 \n" | ||
| 115 | "2: b 1b \n" | ||
| 116 | " .previous \n" | ||
| 114 | " .set mips0 \n" | 117 | " .set mips0 \n" |
| 115 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 118 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) |
| 116 | : "R" (*m), "Jr" (val) | 119 | : "R" (*m), "Jr" (val) |
| @@ -155,7 +158,10 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) | |||
| 155 | "1: lld %0, %3 # xchg_u64 \n" | 158 | "1: lld %0, %3 # xchg_u64 \n" |
| 156 | " move %2, %z4 \n" | 159 | " move %2, %z4 \n" |
| 157 | " scd %2, %1 \n" | 160 | " scd %2, %1 \n" |
| 158 | " beqz %2, 1b \n" | 161 | " beqz %2, 2f \n" |
| 162 | " .subsection 2 \n" | ||
| 163 | "2: b 1b \n" | ||
| 164 | " .previous \n" | ||
| 159 | " .set mips0 \n" | 165 | " .set mips0 \n" |
| 160 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 166 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) |
| 161 | : "R" (*m), "Jr" (val) | 167 | : "R" (*m), "Jr" (val) |
| @@ -232,8 +238,11 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old, | |||
| 232 | " move $1, %z4 \n" | 238 | " move $1, %z4 \n" |
| 233 | " .set mips3 \n" | 239 | " .set mips3 \n" |
| 234 | " sc $1, %1 \n" | 240 | " sc $1, %1 \n" |
| 235 | " beqz $1, 1b \n" | 241 | " beqz $1, 3f \n" |
| 236 | "2: \n" | 242 | "2: \n" |
| 243 | " .subsection 2 \n" | ||
| 244 | "3: b 1b \n" | ||
| 245 | " .previous \n" | ||
| 237 | " .set pop \n" | 246 | " .set pop \n" |
| 238 | : "=&r" (retval), "=R" (*m) | 247 | : "=&r" (retval), "=R" (*m) |
| 239 | : "R" (*m), "Jr" (old), "Jr" (new) | 248 | : "R" (*m), "Jr" (old), "Jr" (new) |
| @@ -283,8 +292,11 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old, | |||
| 283 | " bne %0, %z3, 2f \n" | 292 | " bne %0, %z3, 2f \n" |
| 284 | " move $1, %z4 \n" | 293 | " move $1, %z4 \n" |
| 285 | " scd $1, %1 \n" | 294 | " scd $1, %1 \n" |
| 286 | " beqz $1, 1b \n" | 295 | " beqz $1, 3f \n" |
| 287 | "2: \n" | 296 | "2: \n" |
| 297 | " .subsection 2 \n" | ||
| 298 | "3: b 1b \n" | ||
| 299 | " .previous \n" | ||
| 288 | " .set pop \n" | 300 | " .set pop \n" |
| 289 | : "=&r" (retval), "=R" (*m) | 301 | : "=&r" (retval), "=R" (*m) |
| 290 | : "R" (*m), "Jr" (old), "Jr" (new) | 302 | : "R" (*m), "Jr" (old), "Jr" (new) |
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h index 825fcbd9eabd..3eff8d8fe28a 100644 --- a/include/asm-mips/uaccess.h +++ b/include/asm-mips/uaccess.h | |||
| @@ -265,10 +265,14 @@ do { \ | |||
| 265 | */ | 265 | */ |
| 266 | #define __get_user_asm_ll32(val, addr) \ | 266 | #define __get_user_asm_ll32(val, addr) \ |
| 267 | { \ | 267 | { \ |
| 268 | union { \ | ||
| 269 | unsigned long long l; \ | ||
| 270 | __typeof__(*(addr)) t; \ | ||
| 271 | } __gu_tmp; \ | ||
| 272 | \ | ||
| 268 | __asm__ __volatile__( \ | 273 | __asm__ __volatile__( \ |
| 269 | "1: lw %1, (%3) \n" \ | 274 | "1: lw %1, (%3) \n" \ |
| 270 | "2: lw %D1, 4(%3) \n" \ | 275 | "2: lw %D1, 4(%3) \n" \ |
| 271 | " move %0, $0 \n" \ | ||
| 272 | "3: .section .fixup,\"ax\" \n" \ | 276 | "3: .section .fixup,\"ax\" \n" \ |
| 273 | "4: li %0, %4 \n" \ | 277 | "4: li %0, %4 \n" \ |
| 274 | " move %1, $0 \n" \ | 278 | " move %1, $0 \n" \ |
| @@ -279,8 +283,10 @@ do { \ | |||
| 279 | " " __UA_ADDR " 1b, 4b \n" \ | 283 | " " __UA_ADDR " 1b, 4b \n" \ |
| 280 | " " __UA_ADDR " 2b, 4b \n" \ | 284 | " " __UA_ADDR " 2b, 4b \n" \ |
| 281 | " .previous \n" \ | 285 | " .previous \n" \ |
| 282 | : "=r" (__gu_err), "=&r" (val) \ | 286 | : "=r" (__gu_err), "=&r" (__gu_tmp.l) \ |
| 283 | : "0" (0), "r" (addr), "i" (-EFAULT)); \ | 287 | : "0" (0), "r" (addr), "i" (-EFAULT)); \ |
| 288 | \ | ||
| 289 | (val) = __gu_tmp.t; \ | ||
| 284 | } | 290 | } |
| 285 | 291 | ||
| 286 | /* | 292 | /* |
