xref: /rk3399_rockchip-uboot/arch/sh/include/asm/bitops.h (revision 819833af39a91fa1c1e8252862bbda6f5a602f7b)
1*819833afSPeter Tyser #ifndef __ASM_SH_BITOPS_H
2*819833afSPeter Tyser #define __ASM_SH_BITOPS_H
3*819833afSPeter Tyser 
4*819833afSPeter Tyser #ifdef __KERNEL__
5*819833afSPeter Tyser #include <asm/irqflags.h>
6*819833afSPeter Tyser /* For __swab32 */
7*819833afSPeter Tyser #include <asm/byteorder.h>
8*819833afSPeter Tyser 
9*819833afSPeter Tyser static inline void set_bit(int nr, volatile void * addr)
10*819833afSPeter Tyser {
11*819833afSPeter Tyser 	int	mask;
12*819833afSPeter Tyser 	volatile unsigned int *a = addr;
13*819833afSPeter Tyser 	unsigned long flags;
14*819833afSPeter Tyser 
15*819833afSPeter Tyser 	a += nr >> 5;
16*819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
17*819833afSPeter Tyser 	local_irq_save(flags);
18*819833afSPeter Tyser 	*a |= mask;
19*819833afSPeter Tyser 	local_irq_restore(flags);
20*819833afSPeter Tyser }
21*819833afSPeter Tyser 
22*819833afSPeter Tyser /*
23*819833afSPeter Tyser  * clear_bit() doesn't provide any barrier for the compiler.
24*819833afSPeter Tyser  */
25*819833afSPeter Tyser #define smp_mb__before_clear_bit()	barrier()
26*819833afSPeter Tyser #define smp_mb__after_clear_bit()	barrier()
27*819833afSPeter Tyser static inline void clear_bit(int nr, volatile void * addr)
28*819833afSPeter Tyser {
29*819833afSPeter Tyser 	int	mask;
30*819833afSPeter Tyser 	volatile unsigned int *a = addr;
31*819833afSPeter Tyser 	unsigned long flags;
32*819833afSPeter Tyser 
33*819833afSPeter Tyser 	a += nr >> 5;
34*819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
35*819833afSPeter Tyser 	local_irq_save(flags);
36*819833afSPeter Tyser 	*a &= ~mask;
37*819833afSPeter Tyser 	local_irq_restore(flags);
38*819833afSPeter Tyser }
39*819833afSPeter Tyser 
40*819833afSPeter Tyser static inline void change_bit(int nr, volatile void * addr)
41*819833afSPeter Tyser {
42*819833afSPeter Tyser 	int	mask;
43*819833afSPeter Tyser 	volatile unsigned int *a = addr;
44*819833afSPeter Tyser 	unsigned long flags;
45*819833afSPeter Tyser 
46*819833afSPeter Tyser 	a += nr >> 5;
47*819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
48*819833afSPeter Tyser 	local_irq_save(flags);
49*819833afSPeter Tyser 	*a ^= mask;
50*819833afSPeter Tyser 	local_irq_restore(flags);
51*819833afSPeter Tyser }
52*819833afSPeter Tyser 
53*819833afSPeter Tyser static inline int test_and_set_bit(int nr, volatile void * addr)
54*819833afSPeter Tyser {
55*819833afSPeter Tyser 	int	mask, retval;
56*819833afSPeter Tyser 	volatile unsigned int *a = addr;
57*819833afSPeter Tyser 	unsigned long flags;
58*819833afSPeter Tyser 
59*819833afSPeter Tyser 	a += nr >> 5;
60*819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
61*819833afSPeter Tyser 	local_irq_save(flags);
62*819833afSPeter Tyser 	retval = (mask & *a) != 0;
63*819833afSPeter Tyser 	*a |= mask;
64*819833afSPeter Tyser 	local_irq_restore(flags);
65*819833afSPeter Tyser 
66*819833afSPeter Tyser 	return retval;
67*819833afSPeter Tyser }
68*819833afSPeter Tyser 
69*819833afSPeter Tyser static inline int test_and_clear_bit(int nr, volatile void * addr)
70*819833afSPeter Tyser {
71*819833afSPeter Tyser 	int	mask, retval;
72*819833afSPeter Tyser 	volatile unsigned int *a = addr;
73*819833afSPeter Tyser 	unsigned long flags;
74*819833afSPeter Tyser 
75*819833afSPeter Tyser 	a += nr >> 5;
76*819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
77*819833afSPeter Tyser 	local_irq_save(flags);
78*819833afSPeter Tyser 	retval = (mask & *a) != 0;
79*819833afSPeter Tyser 	*a &= ~mask;
80*819833afSPeter Tyser 	local_irq_restore(flags);
81*819833afSPeter Tyser 
82*819833afSPeter Tyser 	return retval;
83*819833afSPeter Tyser }
84*819833afSPeter Tyser 
85*819833afSPeter Tyser static inline int test_and_change_bit(int nr, volatile void * addr)
86*819833afSPeter Tyser {
87*819833afSPeter Tyser 	int	mask, retval;
88*819833afSPeter Tyser 	volatile unsigned int *a = addr;
89*819833afSPeter Tyser 	unsigned long flags;
90*819833afSPeter Tyser 
91*819833afSPeter Tyser 	a += nr >> 5;
92*819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
93*819833afSPeter Tyser 	local_irq_save(flags);
94*819833afSPeter Tyser 	retval = (mask & *a) != 0;
95*819833afSPeter Tyser 	*a ^= mask;
96*819833afSPeter Tyser 	local_irq_restore(flags);
97*819833afSPeter Tyser 
98*819833afSPeter Tyser 	return retval;
99*819833afSPeter Tyser }
100*819833afSPeter Tyser 
101*819833afSPeter Tyser static inline unsigned long ffz(unsigned long word)
102*819833afSPeter Tyser {
103*819833afSPeter Tyser 	unsigned long result;
104*819833afSPeter Tyser 
105*819833afSPeter Tyser 	__asm__("1:\n\t"
106*819833afSPeter Tyser 		"shlr	%1\n\t"
107*819833afSPeter Tyser 		"bt/s	1b\n\t"
108*819833afSPeter Tyser 		" add	#1, %0"
109*819833afSPeter Tyser 		: "=r" (result), "=r" (word)
110*819833afSPeter Tyser 		: "0" (~0L), "1" (word)
111*819833afSPeter Tyser 		: "t");
112*819833afSPeter Tyser 	return result;
113*819833afSPeter Tyser }
114*819833afSPeter Tyser 
115*819833afSPeter Tyser /**
116*819833afSPeter Tyser  * ffs - find first bit in word.
117*819833afSPeter Tyser  * @word: The word to search
118*819833afSPeter Tyser  *
119*819833afSPeter Tyser  * Undefined if no bit exists, so code should check against 0 first.
120*819833afSPeter Tyser  */
121*819833afSPeter Tyser static inline int ffs (int x)
122*819833afSPeter Tyser {
123*819833afSPeter Tyser 	int r = 1;
124*819833afSPeter Tyser 
125*819833afSPeter Tyser 	if (!x)
126*819833afSPeter Tyser 		return 0;
127*819833afSPeter Tyser 	if (!(x & 0xffff)) {
128*819833afSPeter Tyser 		x >>= 16;
129*819833afSPeter Tyser 		r += 16;
130*819833afSPeter Tyser 	}
131*819833afSPeter Tyser 	if (!(x & 0xff)) {
132*819833afSPeter Tyser 		x >>= 8;
133*819833afSPeter Tyser 		r += 8;
134*819833afSPeter Tyser 	}
135*819833afSPeter Tyser 	if (!(x & 0xf)) {
136*819833afSPeter Tyser 		x >>= 4;
137*819833afSPeter Tyser 		r += 4;
138*819833afSPeter Tyser 	}
139*819833afSPeter Tyser 	if (!(x & 3)) {
140*819833afSPeter Tyser 		x >>= 2;
141*819833afSPeter Tyser 		r += 2;
142*819833afSPeter Tyser 	}
143*819833afSPeter Tyser 	if (!(x & 1)) {
144*819833afSPeter Tyser 		x >>= 1;
145*819833afSPeter Tyser 		r += 1;
146*819833afSPeter Tyser 	}
147*819833afSPeter Tyser 	return r;
148*819833afSPeter Tyser }
149*819833afSPeter Tyser #define PLATFORM_FFS
150*819833afSPeter Tyser 
151*819833afSPeter Tyser #endif /* __KERNEL__ */
152*819833afSPeter Tyser 
153*819833afSPeter Tyser #endif /* __ASM_SH_BITOPS_H */
154