blob: d8328be0619113d254de7a9f2deec3648feee404 [file] [log] [blame]
Paul Mundt742fd1b2008-08-07 17:36:12 +09001#ifndef __ASM_SH_BITOPS_LLSC_H
2#define __ASM_SH_BITOPS_LLSC_H
3
Matt Fleming42990702009-01-20 21:14:37 +00004static inline void set_bit(int nr, volatile void *addr)
Paul Mundt742fd1b2008-08-07 17:36:12 +09005{
6 int mask;
7 volatile unsigned int *a = addr;
8 unsigned long tmp;
9
10 a += nr >> 5;
11 mask = 1 << (nr & 0x1f);
12
13 __asm__ __volatile__ (
14 "1: \n\t"
15 "movli.l @%1, %0 ! set_bit \n\t"
Matt Fleming42990702009-01-20 21:14:37 +000016 "or %2, %0 \n\t"
Paul Mundt742fd1b2008-08-07 17:36:12 +090017 "movco.l %0, @%1 \n\t"
18 "bf 1b \n\t"
Matt Fleming42990702009-01-20 21:14:37 +000019 : "=&z" (tmp)
20 : "r" (a), "r" (mask)
Paul Mundt742fd1b2008-08-07 17:36:12 +090021 : "t", "memory"
22 );
23}
24
Matt Fleming42990702009-01-20 21:14:37 +000025static inline void clear_bit(int nr, volatile void *addr)
Paul Mundt742fd1b2008-08-07 17:36:12 +090026{
27 int mask;
28 volatile unsigned int *a = addr;
29 unsigned long tmp;
30
31 a += nr >> 5;
32 mask = 1 << (nr & 0x1f);
33
34 __asm__ __volatile__ (
35 "1: \n\t"
36 "movli.l @%1, %0 ! clear_bit \n\t"
Matt Fleming42990702009-01-20 21:14:37 +000037 "and %2, %0 \n\t"
Paul Mundt742fd1b2008-08-07 17:36:12 +090038 "movco.l %0, @%1 \n\t"
39 "bf 1b \n\t"
Matt Fleming42990702009-01-20 21:14:37 +000040 : "=&z" (tmp)
41 : "r" (a), "r" (~mask)
Paul Mundt742fd1b2008-08-07 17:36:12 +090042 : "t", "memory"
43 );
44}
45
Matt Fleming42990702009-01-20 21:14:37 +000046static inline void change_bit(int nr, volatile void *addr)
Paul Mundt742fd1b2008-08-07 17:36:12 +090047{
48 int mask;
49 volatile unsigned int *a = addr;
50 unsigned long tmp;
51
52 a += nr >> 5;
53 mask = 1 << (nr & 0x1f);
54
55 __asm__ __volatile__ (
56 "1: \n\t"
57 "movli.l @%1, %0 ! change_bit \n\t"
Matt Fleming42990702009-01-20 21:14:37 +000058 "xor %2, %0 \n\t"
59 "movco.l %0, @%1 \n\t"
60 "bf 1b \n\t"
61 : "=&z" (tmp)
62 : "r" (a), "r" (mask)
63 : "t", "memory"
64 );
65}
66
67static inline int test_and_set_bit(int nr, volatile void *addr)
68{
69 int mask, retval;
70 volatile unsigned int *a = addr;
71 unsigned long tmp;
72
73 a += nr >> 5;
74 mask = 1 << (nr & 0x1f);
75
76 __asm__ __volatile__ (
77 "1: \n\t"
78 "movli.l @%2, %0 ! test_and_set_bit \n\t"
79 "mov %0, %1 \n\t"
80 "or %3, %0 \n\t"
81 "movco.l %0, @%2 \n\t"
82 "bf 1b \n\t"
83 "and %3, %1 \n\t"
84 : "=&z" (tmp), "=&r" (retval)
85 : "r" (a), "r" (mask)
86 : "t", "memory"
87 );
88
89 return retval != 0;
90}
91
92static inline int test_and_clear_bit(int nr, volatile void *addr)
93{
94 int mask, retval;
95 volatile unsigned int *a = addr;
96 unsigned long tmp;
97
98 a += nr >> 5;
99 mask = 1 << (nr & 0x1f);
100
101 __asm__ __volatile__ (
102 "1: \n\t"
103 "movli.l @%2, %0 ! test_and_clear_bit \n\t"
104 "mov %0, %1 \n\t"
105 "and %4, %0 \n\t"
106 "movco.l %0, @%2 \n\t"
107 "bf 1b \n\t"
108 "and %3, %1 \n\t"
109 "synco \n\t"
110 : "=&z" (tmp), "=&r" (retval)
111 : "r" (a), "r" (mask), "r" (~mask)
112 : "t", "memory"
113 );
114
115 return retval != 0;
116}
117
118static inline int test_and_change_bit(int nr, volatile void *addr)
119{
120 int mask, retval;
121 volatile unsigned int *a = addr;
122 unsigned long tmp;
123
124 a += nr >> 5;
125 mask = 1 << (nr & 0x1f);
126
127 __asm__ __volatile__ (
128 "1: \n\t"
129 "movli.l @%2, %0 ! test_and_change_bit \n\t"
130 "mov %0, %1 \n\t"
Paul Mundt742fd1b2008-08-07 17:36:12 +0900131 "xor %3, %0 \n\t"
Matt Fleming42990702009-01-20 21:14:37 +0000132 "movco.l %0, @%2 \n\t"
Paul Mundt742fd1b2008-08-07 17:36:12 +0900133 "bf 1b \n\t"
Matt Fleming42990702009-01-20 21:14:37 +0000134 "and %3, %1 \n\t"
Paul Mundt742fd1b2008-08-07 17:36:12 +0900135 "synco \n\t"
Matt Fleming42990702009-01-20 21:14:37 +0000136 : "=&z" (tmp), "=&r" (retval)
137 : "r" (a), "r" (mask)
Paul Mundt742fd1b2008-08-07 17:36:12 +0900138 : "t", "memory"
139 );
140
141 return retval != 0;
142}
143
Paul Mundt16b529d2008-11-20 15:25:22 +0900144#include <asm-generic/bitops/non-atomic.h>
145
Paul Mundt742fd1b2008-08-07 17:36:12 +0900146#endif /* __ASM_SH_BITOPS_LLSC_H */