at v5.13 128 lines 2.9 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _ASM_GENERIC_BITOPS_LE_H_ 3#define _ASM_GENERIC_BITOPS_LE_H_ 4 5#include <asm-generic/bitops/find.h> 6#include <asm/types.h> 7#include <asm/byteorder.h> 8#include <linux/swab.h> 9 10#if defined(__LITTLE_ENDIAN) 11 12#define BITOP_LE_SWIZZLE 0 13 14static inline unsigned long find_next_zero_bit_le(const void *addr, 15 unsigned long size, unsigned long offset) 16{ 17 return find_next_zero_bit(addr, size, offset); 18} 19 20static inline unsigned long find_next_bit_le(const void *addr, 21 unsigned long size, unsigned long offset) 22{ 23 return find_next_bit(addr, size, offset); 24} 25 26static inline unsigned long find_first_zero_bit_le(const void *addr, 27 unsigned long size) 28{ 29 return find_first_zero_bit(addr, size); 30} 31 32#elif defined(__BIG_ENDIAN) 33 34#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7) 35 36#ifndef find_next_zero_bit_le 37static inline 38unsigned long find_next_zero_bit_le(const void *addr, unsigned 39 long size, unsigned long offset) 40{ 41 if (small_const_nbits(size)) { 42 unsigned long val = *(const unsigned long *)addr; 43 44 if (unlikely(offset >= size)) 45 return size; 46 47 val = swab(val) | ~GENMASK(size - 1, offset); 48 return val == ~0UL ? size : ffz(val); 49 } 50 51 return _find_next_bit(addr, NULL, size, offset, ~0UL, 1); 52} 53#endif 54 55#ifndef find_next_bit_le 56static inline 57unsigned long find_next_bit_le(const void *addr, unsigned 58 long size, unsigned long offset) 59{ 60 if (small_const_nbits(size)) { 61 unsigned long val = *(const unsigned long *)addr; 62 63 if (unlikely(offset >= size)) 64 return size; 65 66 val = swab(val) & GENMASK(size - 1, offset); 67 return val ? __ffs(val) : size; 68 } 69 70 return _find_next_bit(addr, NULL, size, offset, 0UL, 1); 71} 72#endif 73 74#ifndef find_first_zero_bit_le 75#define find_first_zero_bit_le(addr, size) \ 76 find_next_zero_bit_le((addr), (size), 0) 77#endif 78 79#else 80#error "Please fix <asm/byteorder.h>" 81#endif 82 83static inline int test_bit_le(int nr, const void *addr) 84{ 85 return test_bit(nr ^ BITOP_LE_SWIZZLE, addr); 86} 87 88static inline void set_bit_le(int nr, void *addr) 89{ 90 set_bit(nr ^ BITOP_LE_SWIZZLE, addr); 91} 92 93static inline void clear_bit_le(int nr, void *addr) 94{ 95 clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); 96} 97 98static inline void __set_bit_le(int nr, void *addr) 99{ 100 __set_bit(nr ^ BITOP_LE_SWIZZLE, addr); 101} 102 103static inline void __clear_bit_le(int nr, void *addr) 104{ 105 __clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); 106} 107 108static inline int test_and_set_bit_le(int nr, void *addr) 109{ 110 return test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr); 111} 112 113static inline int test_and_clear_bit_le(int nr, void *addr) 114{ 115 return test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); 116} 117 118static inline int __test_and_set_bit_le(int nr, void *addr) 119{ 120 return __test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr); 121} 122 123static inline int __test_and_clear_bit_le(int nr, void *addr) 124{ 125 return __test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); 126} 127 128#endif /* _ASM_GENERIC_BITOPS_LE_H_ */