#ifndef _ARM_ARM64_BITOPS_H
#define _ARM_ARM64_BITOPS_H

/*
 * Little endian assembly atomic bitops.
 */
extern void set_bit(int nr, volatile void *p);
extern void clear_bit(int nr, volatile void *p);
extern void change_bit(int nr, volatile void *p);
extern int test_and_set_bit(int nr, volatile void *p);
extern int test_and_clear_bit(int nr, volatile void *p);
extern int test_and_change_bit(int nr, volatile void *p);

/* Based on linux/include/asm-generic/bitops/builtin-__ffs.h */
/**
 * __ffs - find first bit in word.
 * @word: The word to search
 *
 * Undefined if no bit exists, so code should check against 0 first.
 */
static /*__*/always_inline unsigned long __ffs(unsigned long word)
{
        return __builtin_ctzl(word);
}

/* Based on linux/include/asm-generic/bitops/ffz.h */
/*
 * ffz - find first zero in word.
 * @word: The word to search
 *
 * Undefined if no zero exists, so code should check against ~0UL first.
 */
#define ffz(x)  __ffs(~(x))

static inline int flsl(unsigned long x)
{
        int ret;

        if (__builtin_constant_p(x))
               return generic_flsl(x);

        asm("clz\t%0, %1" : "=r" (ret) : "r" (x));
        return BITS_PER_LONG - ret;
}

/* Based on linux/include/asm-generic/bitops/find.h */

#ifndef find_next_bit
/**
 * find_next_bit - find the next set bit in a memory region
 * @addr: The address to base the search on
 * @offset: The bitnumber to start searching at
 * @size: The bitmap size in bits
 */
extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
		size, unsigned long offset);
#endif

#ifndef find_next_zero_bit
/**
 * find_next_zero_bit - find the next cleared bit in a memory region
 * @addr: The address to base the search on
 * @offset: The bitnumber to start searching at
 * @size: The bitmap size in bits
 */
extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned
		long size, unsigned long offset);
#endif

#ifdef CONFIG_GENERIC_FIND_FIRST_BIT

/**
 * find_first_bit - find the first set bit in a memory region
 * @addr: The address to start the search at
 * @size: The maximum size to search
 *
 * Returns the bit number of the first set bit.
 */
extern unsigned long find_first_bit(const unsigned long *addr,
				    unsigned long size);

/**
 * find_first_zero_bit - find the first cleared bit in a memory region
 * @addr: The address to start the search at
 * @size: The maximum size to search
 *
 * Returns the bit number of the first cleared bit.
 */
extern unsigned long find_first_zero_bit(const unsigned long *addr,
					 unsigned long size);
#else /* CONFIG_GENERIC_FIND_FIRST_BIT */

#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)

#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */


#endif /* _ARM_ARM64_BITOPS_H */
/*
 * Local variables:
 * mode: C
 * c-file-style: "BSD"
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * End:
 */
