spinlock.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #ifndef __ASM_SPINLOCK_H
  2. #define __ASM_SPINLOCK_H
  3. #include <asm/system.h>
  4. /*
  5. * Simple spin lock operations.
  6. *
  7. * (the type definitions are in asm/raw_spinlock_types.h)
  8. */
  9. #define __raw_spin_is_locked(x) ((x)->slock != 0)
  10. #define __raw_spin_unlock_wait(lock) \
  11. do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
  12. #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
  13. static inline void __raw_spin_lock(raw_spinlock_t *lock)
  14. {
  15. unsigned long tmp;
  16. __asm__ __volatile__(
  17. "b 1f # __raw_spin_lock\n\
  18. 2: lwzx %0,0,%1\n\
  19. cmpwi 0,%0,0\n\
  20. bne+ 2b\n\
  21. 1: lwarx %0,0,%1\n\
  22. cmpwi 0,%0,0\n\
  23. bne- 2b\n"
  24. PPC405_ERR77(0,%1)
  25. " stwcx. %2,0,%1\n\
  26. bne- 2b\n\
  27. isync"
  28. : "=&r"(tmp)
  29. : "r"(&lock->slock), "r"(1)
  30. : "cr0", "memory");
  31. }
  32. static inline void __raw_spin_unlock(raw_spinlock_t *lock)
  33. {
  34. __asm__ __volatile__("eieio # __raw_spin_unlock": : :"memory");
  35. lock->slock = 0;
  36. }
  37. #define __raw_spin_trylock(l) (!test_and_set_bit(0,(volatile unsigned long *)(&(l)->slock)))
  38. /*
  39. * Read-write spinlocks, allowing multiple readers
  40. * but only one writer.
  41. *
  42. * NOTE! it is quite common to have readers in interrupts
  43. * but no interrupt writers. For those circumstances we
  44. * can "mix" irq-safe locks - any writer needs to get a
  45. * irq-safe write-lock, but readers can get non-irqsafe
  46. * read-locks.
  47. */
  48. #define __raw_read_can_lock(rw) ((rw)->lock >= 0)
  49. #define __raw_write_can_lock(rw) (!(rw)->lock)
  50. static __inline__ int __raw_read_trylock(raw_rwlock_t *rw)
  51. {
  52. signed int tmp;
  53. __asm__ __volatile__(
  54. "2: lwarx %0,0,%1 # read_trylock\n\
  55. addic. %0,%0,1\n\
  56. ble- 1f\n"
  57. PPC405_ERR77(0,%1)
  58. " stwcx. %0,0,%1\n\
  59. bne- 2b\n\
  60. isync\n\
  61. 1:"
  62. : "=&r"(tmp)
  63. : "r"(&rw->lock)
  64. : "cr0", "memory");
  65. return tmp > 0;
  66. }
  67. static __inline__ void __raw_read_lock(raw_rwlock_t *rw)
  68. {
  69. signed int tmp;
  70. __asm__ __volatile__(
  71. "b 2f # read_lock\n\
  72. 1: lwzx %0,0,%1\n\
  73. cmpwi 0,%0,0\n\
  74. blt+ 1b\n\
  75. 2: lwarx %0,0,%1\n\
  76. addic. %0,%0,1\n\
  77. ble- 1b\n"
  78. PPC405_ERR77(0,%1)
  79. " stwcx. %0,0,%1\n\
  80. bne- 2b\n\
  81. isync"
  82. : "=&r"(tmp)
  83. : "r"(&rw->lock)
  84. : "cr0", "memory");
  85. }
  86. static __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
  87. {
  88. signed int tmp;
  89. __asm__ __volatile__(
  90. "eieio # read_unlock\n\
  91. 1: lwarx %0,0,%1\n\
  92. addic %0,%0,-1\n"
  93. PPC405_ERR77(0,%1)
  94. " stwcx. %0,0,%1\n\
  95. bne- 1b"
  96. : "=&r"(tmp)
  97. : "r"(&rw->lock)
  98. : "cr0", "memory");
  99. }
  100. static __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
  101. {
  102. signed int tmp;
  103. __asm__ __volatile__(
  104. "2: lwarx %0,0,%1 # write_trylock\n\
  105. cmpwi 0,%0,0\n\
  106. bne- 1f\n"
  107. PPC405_ERR77(0,%1)
  108. " stwcx. %2,0,%1\n\
  109. bne- 2b\n\
  110. isync\n\
  111. 1:"
  112. : "=&r"(tmp)
  113. : "r"(&rw->lock), "r"(-1)
  114. : "cr0", "memory");
  115. return tmp == 0;
  116. }
  117. static __inline__ void __raw_write_lock(raw_rwlock_t *rw)
  118. {
  119. signed int tmp;
  120. __asm__ __volatile__(
  121. "b 2f # write_lock\n\
  122. 1: lwzx %0,0,%1\n\
  123. cmpwi 0,%0,0\n\
  124. bne+ 1b\n\
  125. 2: lwarx %0,0,%1\n\
  126. cmpwi 0,%0,0\n\
  127. bne- 1b\n"
  128. PPC405_ERR77(0,%1)
  129. " stwcx. %2,0,%1\n\
  130. bne- 2b\n\
  131. isync"
  132. : "=&r"(tmp)
  133. : "r"(&rw->lock), "r"(-1)
  134. : "cr0", "memory");
  135. }
  136. static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
  137. {
  138. __asm__ __volatile__("eieio # write_unlock": : :"memory");
  139. rw->lock = 0;
  140. }
  141. #endif /* __ASM_SPINLOCK_H */