diff options
Diffstat (limited to 'include/linux/log2.h')
| -rw-r--r-- | include/linux/log2.h | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/include/linux/log2.h b/include/linux/log2.h index 83a4a3ca3e8a..2eac3fc9303d 100644 --- a/include/linux/log2.h +++ b/include/linux/log2.h @@ -18,7 +18,7 @@ * - the arch is not required to handle n==0 if implementing the fallback */ #ifndef CONFIG_ARCH_HAS_ILOG2_U32 -static inline __attribute__((const)) +static __always_inline __attribute__((const)) int __ilog2_u32(u32 n) { return fls(n) - 1; @@ -26,7 +26,7 @@ int __ilog2_u32(u32 n) #endif #ifndef CONFIG_ARCH_HAS_ILOG2_U64 -static inline __attribute__((const)) +static __always_inline __attribute__((const)) int __ilog2_u64(u64 n) { return fls64(n) - 1; @@ -41,7 +41,7 @@ int __ilog2_u64(u64 n) * *not* considered a power of two. * Return: true if @n is a power of 2, otherwise false. */ -static inline __attribute__((const)) +static __always_inline __attribute__((const)) bool is_power_of_2(unsigned long n) { return (n != 0 && ((n & (n - 1)) == 0)); @@ -156,7 +156,8 @@ unsigned long __rounddown_pow_of_two(unsigned long n) #define ilog2(n) \ ( \ __builtin_constant_p(n) ? \ - const_ilog2(n) : \ + ((n) < 2 ? 0 : \ + 63 - __builtin_clzll(n)) : \ (sizeof(n) <= 4) ? \ __ilog2_u32(n) : \ __ilog2_u64(n) \ @@ -173,7 +174,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) #define roundup_pow_of_two(n) \ ( \ __builtin_constant_p(n) ? ( \ - (n == 1) ? 1 : \ + ((n) == 1) ? 1 : \ (1UL << (ilog2((n) - 1) + 1)) \ ) : \ __roundup_pow_of_two(n) \ @@ -254,4 +255,18 @@ int __bits_per(unsigned long n) ) : \ __bits_per(n) \ ) + +/** + * max_pow_of_two_factor - return highest power-of-2 factor + * @n: parameter + * + * find highest power-of-2 which is evenly divisible into n. + * 0 is returned for n == 0 or 1. + */ +static inline __attribute__((const)) +unsigned int max_pow_of_two_factor(unsigned int n) +{ + return n & -n; +} + #endif /* _LINUX_LOG2_H */ |
