18c2ecf20Sopenharmony_ci#ifndef _M68K_BITOPS_H
28c2ecf20Sopenharmony_ci#define _M68K_BITOPS_H
38c2ecf20Sopenharmony_ci/*
48c2ecf20Sopenharmony_ci * Copyright 1992, Linus Torvalds.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
78c2ecf20Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
88c2ecf20Sopenharmony_ci * for more details.
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef _LINUX_BITOPS_H
128c2ecf20Sopenharmony_ci#error only <linux/bitops.h> can be included directly
138c2ecf20Sopenharmony_ci#endif
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <linux/compiler.h>
168c2ecf20Sopenharmony_ci#include <asm/barrier.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/*
198c2ecf20Sopenharmony_ci *	Bit access functions vary across the ColdFire and 68k families.
208c2ecf20Sopenharmony_ci *	So we will break them out here, and then macro in the ones we want.
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci *	ColdFire - supports standard bset/bclr/bchg with register operand only
238c2ecf20Sopenharmony_ci *	68000    - supports standard bset/bclr/bchg with memory operand
248c2ecf20Sopenharmony_ci *	>= 68020 - also supports the bfset/bfclr/bfchg instructions
258c2ecf20Sopenharmony_ci *
268c2ecf20Sopenharmony_ci *	Although it is possible to use only the bset/bclr/bchg with register
278c2ecf20Sopenharmony_ci *	operands on all platforms you end up with larger generated code.
288c2ecf20Sopenharmony_ci *	So we use the best form possible on a given platform.
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic inline void bset_reg_set_bit(int nr, volatile unsigned long *vaddr)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bset %1,(%0)"
368c2ecf20Sopenharmony_ci		:
378c2ecf20Sopenharmony_ci		: "a" (p), "di" (nr & 7)
388c2ecf20Sopenharmony_ci		: "memory");
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cistatic inline void bset_mem_set_bit(int nr, volatile unsigned long *vaddr)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bset %1,%0"
468c2ecf20Sopenharmony_ci		: "+m" (*p)
478c2ecf20Sopenharmony_ci		: "di" (nr & 7));
488c2ecf20Sopenharmony_ci}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cistatic inline void bfset_mem_set_bit(int nr, volatile unsigned long *vaddr)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bfset %1{%0:#1}"
538c2ecf20Sopenharmony_ci		:
548c2ecf20Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
558c2ecf20Sopenharmony_ci		: "memory");
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
598c2ecf20Sopenharmony_ci#define	set_bit(nr, vaddr)	bset_reg_set_bit(nr, vaddr)
608c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
618c2ecf20Sopenharmony_ci#define	set_bit(nr, vaddr)	bset_mem_set_bit(nr, vaddr)
628c2ecf20Sopenharmony_ci#else
638c2ecf20Sopenharmony_ci#define set_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
648c2ecf20Sopenharmony_ci				bset_mem_set_bit(nr, vaddr) : \
658c2ecf20Sopenharmony_ci				bfset_mem_set_bit(nr, vaddr))
668c2ecf20Sopenharmony_ci#endif
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci#define __set_bit(nr, vaddr)	set_bit(nr, vaddr)
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic inline void bclr_reg_clear_bit(int nr, volatile unsigned long *vaddr)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bclr %1,(%0)"
768c2ecf20Sopenharmony_ci		:
778c2ecf20Sopenharmony_ci		: "a" (p), "di" (nr & 7)
788c2ecf20Sopenharmony_ci		: "memory");
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistatic inline void bclr_mem_clear_bit(int nr, volatile unsigned long *vaddr)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bclr %1,%0"
868c2ecf20Sopenharmony_ci		: "+m" (*p)
878c2ecf20Sopenharmony_ci		: "di" (nr & 7));
888c2ecf20Sopenharmony_ci}
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_cistatic inline void bfclr_mem_clear_bit(int nr, volatile unsigned long *vaddr)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bfclr %1{%0:#1}"
938c2ecf20Sopenharmony_ci		:
948c2ecf20Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
958c2ecf20Sopenharmony_ci		: "memory");
968c2ecf20Sopenharmony_ci}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
998c2ecf20Sopenharmony_ci#define	clear_bit(nr, vaddr)	bclr_reg_clear_bit(nr, vaddr)
1008c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
1018c2ecf20Sopenharmony_ci#define	clear_bit(nr, vaddr)	bclr_mem_clear_bit(nr, vaddr)
1028c2ecf20Sopenharmony_ci#else
1038c2ecf20Sopenharmony_ci#define clear_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
1048c2ecf20Sopenharmony_ci				bclr_mem_clear_bit(nr, vaddr) : \
1058c2ecf20Sopenharmony_ci				bfclr_mem_clear_bit(nr, vaddr))
1068c2ecf20Sopenharmony_ci#endif
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci#define __clear_bit(nr, vaddr)	clear_bit(nr, vaddr)
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cistatic inline void bchg_reg_change_bit(int nr, volatile unsigned long *vaddr)
1128c2ecf20Sopenharmony_ci{
1138c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bchg %1,(%0)"
1168c2ecf20Sopenharmony_ci		:
1178c2ecf20Sopenharmony_ci		: "a" (p), "di" (nr & 7)
1188c2ecf20Sopenharmony_ci		: "memory");
1198c2ecf20Sopenharmony_ci}
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_cistatic inline void bchg_mem_change_bit(int nr, volatile unsigned long *vaddr)
1228c2ecf20Sopenharmony_ci{
1238c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bchg %1,%0"
1268c2ecf20Sopenharmony_ci		: "+m" (*p)
1278c2ecf20Sopenharmony_ci		: "di" (nr & 7));
1288c2ecf20Sopenharmony_ci}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic inline void bfchg_mem_change_bit(int nr, volatile unsigned long *vaddr)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bfchg %1{%0:#1}"
1338c2ecf20Sopenharmony_ci		:
1348c2ecf20Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
1358c2ecf20Sopenharmony_ci		: "memory");
1368c2ecf20Sopenharmony_ci}
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
1398c2ecf20Sopenharmony_ci#define	change_bit(nr, vaddr)	bchg_reg_change_bit(nr, vaddr)
1408c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
1418c2ecf20Sopenharmony_ci#define	change_bit(nr, vaddr)	bchg_mem_change_bit(nr, vaddr)
1428c2ecf20Sopenharmony_ci#else
1438c2ecf20Sopenharmony_ci#define change_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
1448c2ecf20Sopenharmony_ci				bchg_mem_change_bit(nr, vaddr) : \
1458c2ecf20Sopenharmony_ci				bfchg_mem_change_bit(nr, vaddr))
1468c2ecf20Sopenharmony_ci#endif
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci#define __change_bit(nr, vaddr)	change_bit(nr, vaddr)
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic inline int test_bit(int nr, const volatile unsigned long *vaddr)
1528c2ecf20Sopenharmony_ci{
1538c2ecf20Sopenharmony_ci	return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0;
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic inline int bset_reg_test_and_set_bit(int nr,
1588c2ecf20Sopenharmony_ci					    volatile unsigned long *vaddr)
1598c2ecf20Sopenharmony_ci{
1608c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
1618c2ecf20Sopenharmony_ci	char retval;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bset %2,(%1); sne %0"
1648c2ecf20Sopenharmony_ci		: "=d" (retval)
1658c2ecf20Sopenharmony_ci		: "a" (p), "di" (nr & 7)
1668c2ecf20Sopenharmony_ci		: "memory");
1678c2ecf20Sopenharmony_ci	return retval;
1688c2ecf20Sopenharmony_ci}
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistatic inline int bset_mem_test_and_set_bit(int nr,
1718c2ecf20Sopenharmony_ci					    volatile unsigned long *vaddr)
1728c2ecf20Sopenharmony_ci{
1738c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
1748c2ecf20Sopenharmony_ci	char retval;
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bset %2,%1; sne %0"
1778c2ecf20Sopenharmony_ci		: "=d" (retval), "+m" (*p)
1788c2ecf20Sopenharmony_ci		: "di" (nr & 7));
1798c2ecf20Sopenharmony_ci	return retval;
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic inline int bfset_mem_test_and_set_bit(int nr,
1838c2ecf20Sopenharmony_ci					     volatile unsigned long *vaddr)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	char retval;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bfset %2{%1:#1}; sne %0"
1888c2ecf20Sopenharmony_ci		: "=d" (retval)
1898c2ecf20Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
1908c2ecf20Sopenharmony_ci		: "memory");
1918c2ecf20Sopenharmony_ci	return retval;
1928c2ecf20Sopenharmony_ci}
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
1958c2ecf20Sopenharmony_ci#define	test_and_set_bit(nr, vaddr)	bset_reg_test_and_set_bit(nr, vaddr)
1968c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
1978c2ecf20Sopenharmony_ci#define	test_and_set_bit(nr, vaddr)	bset_mem_test_and_set_bit(nr, vaddr)
1988c2ecf20Sopenharmony_ci#else
1998c2ecf20Sopenharmony_ci#define test_and_set_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
2008c2ecf20Sopenharmony_ci					bset_mem_test_and_set_bit(nr, vaddr) : \
2018c2ecf20Sopenharmony_ci					bfset_mem_test_and_set_bit(nr, vaddr))
2028c2ecf20Sopenharmony_ci#endif
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci#define __test_and_set_bit(nr, vaddr)	test_and_set_bit(nr, vaddr)
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_cistatic inline int bclr_reg_test_and_clear_bit(int nr,
2088c2ecf20Sopenharmony_ci					      volatile unsigned long *vaddr)
2098c2ecf20Sopenharmony_ci{
2108c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
2118c2ecf20Sopenharmony_ci	char retval;
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bclr %2,(%1); sne %0"
2148c2ecf20Sopenharmony_ci		: "=d" (retval)
2158c2ecf20Sopenharmony_ci		: "a" (p), "di" (nr & 7)
2168c2ecf20Sopenharmony_ci		: "memory");
2178c2ecf20Sopenharmony_ci	return retval;
2188c2ecf20Sopenharmony_ci}
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_cistatic inline int bclr_mem_test_and_clear_bit(int nr,
2218c2ecf20Sopenharmony_ci					      volatile unsigned long *vaddr)
2228c2ecf20Sopenharmony_ci{
2238c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
2248c2ecf20Sopenharmony_ci	char retval;
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bclr %2,%1; sne %0"
2278c2ecf20Sopenharmony_ci		: "=d" (retval), "+m" (*p)
2288c2ecf20Sopenharmony_ci		: "di" (nr & 7));
2298c2ecf20Sopenharmony_ci	return retval;
2308c2ecf20Sopenharmony_ci}
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_cistatic inline int bfclr_mem_test_and_clear_bit(int nr,
2338c2ecf20Sopenharmony_ci					       volatile unsigned long *vaddr)
2348c2ecf20Sopenharmony_ci{
2358c2ecf20Sopenharmony_ci	char retval;
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0"
2388c2ecf20Sopenharmony_ci		: "=d" (retval)
2398c2ecf20Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
2408c2ecf20Sopenharmony_ci		: "memory");
2418c2ecf20Sopenharmony_ci	return retval;
2428c2ecf20Sopenharmony_ci}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
2458c2ecf20Sopenharmony_ci#define	test_and_clear_bit(nr, vaddr)	bclr_reg_test_and_clear_bit(nr, vaddr)
2468c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
2478c2ecf20Sopenharmony_ci#define	test_and_clear_bit(nr, vaddr)	bclr_mem_test_and_clear_bit(nr, vaddr)
2488c2ecf20Sopenharmony_ci#else
2498c2ecf20Sopenharmony_ci#define test_and_clear_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
2508c2ecf20Sopenharmony_ci					bclr_mem_test_and_clear_bit(nr, vaddr) : \
2518c2ecf20Sopenharmony_ci					bfclr_mem_test_and_clear_bit(nr, vaddr))
2528c2ecf20Sopenharmony_ci#endif
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci#define __test_and_clear_bit(nr, vaddr)	test_and_clear_bit(nr, vaddr)
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_cistatic inline int bchg_reg_test_and_change_bit(int nr,
2588c2ecf20Sopenharmony_ci					       volatile unsigned long *vaddr)
2598c2ecf20Sopenharmony_ci{
2608c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
2618c2ecf20Sopenharmony_ci	char retval;
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bchg %2,(%1); sne %0"
2648c2ecf20Sopenharmony_ci		: "=d" (retval)
2658c2ecf20Sopenharmony_ci		: "a" (p), "di" (nr & 7)
2668c2ecf20Sopenharmony_ci		: "memory");
2678c2ecf20Sopenharmony_ci	return retval;
2688c2ecf20Sopenharmony_ci}
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_cistatic inline int bchg_mem_test_and_change_bit(int nr,
2718c2ecf20Sopenharmony_ci					       volatile unsigned long *vaddr)
2728c2ecf20Sopenharmony_ci{
2738c2ecf20Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
2748c2ecf20Sopenharmony_ci	char retval;
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bchg %2,%1; sne %0"
2778c2ecf20Sopenharmony_ci		: "=d" (retval), "+m" (*p)
2788c2ecf20Sopenharmony_ci		: "di" (nr & 7));
2798c2ecf20Sopenharmony_ci	return retval;
2808c2ecf20Sopenharmony_ci}
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_cistatic inline int bfchg_mem_test_and_change_bit(int nr,
2838c2ecf20Sopenharmony_ci						volatile unsigned long *vaddr)
2848c2ecf20Sopenharmony_ci{
2858c2ecf20Sopenharmony_ci	char retval;
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bfchg %2{%1:#1}; sne %0"
2888c2ecf20Sopenharmony_ci		: "=d" (retval)
2898c2ecf20Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
2908c2ecf20Sopenharmony_ci		: "memory");
2918c2ecf20Sopenharmony_ci	return retval;
2928c2ecf20Sopenharmony_ci}
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
2958c2ecf20Sopenharmony_ci#define	test_and_change_bit(nr, vaddr)	bchg_reg_test_and_change_bit(nr, vaddr)
2968c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
2978c2ecf20Sopenharmony_ci#define	test_and_change_bit(nr, vaddr)	bchg_mem_test_and_change_bit(nr, vaddr)
2988c2ecf20Sopenharmony_ci#else
2998c2ecf20Sopenharmony_ci#define test_and_change_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
3008c2ecf20Sopenharmony_ci					bchg_mem_test_and_change_bit(nr, vaddr) : \
3018c2ecf20Sopenharmony_ci					bfchg_mem_test_and_change_bit(nr, vaddr))
3028c2ecf20Sopenharmony_ci#endif
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci#define __test_and_change_bit(nr, vaddr) test_and_change_bit(nr, vaddr)
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci/*
3088c2ecf20Sopenharmony_ci *	The true 68020 and more advanced processors support the "bfffo"
3098c2ecf20Sopenharmony_ci *	instruction for finding bits. ColdFire and simple 68000 parts
3108c2ecf20Sopenharmony_ci *	(including CPU32) do not support this. They simply use the generic
3118c2ecf20Sopenharmony_ci *	functions.
3128c2ecf20Sopenharmony_ci */
3138c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_HAS_NO_BITFIELDS)
3148c2ecf20Sopenharmony_ci#include <asm-generic/bitops/ffz.h>
3158c2ecf20Sopenharmony_ci#else
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_cistatic inline int find_first_zero_bit(const unsigned long *vaddr,
3188c2ecf20Sopenharmony_ci				      unsigned size)
3198c2ecf20Sopenharmony_ci{
3208c2ecf20Sopenharmony_ci	const unsigned long *p = vaddr;
3218c2ecf20Sopenharmony_ci	int res = 32;
3228c2ecf20Sopenharmony_ci	unsigned int words;
3238c2ecf20Sopenharmony_ci	unsigned long num;
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	if (!size)
3268c2ecf20Sopenharmony_ci		return 0;
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci	words = (size + 31) >> 5;
3298c2ecf20Sopenharmony_ci	while (!(num = ~*p++)) {
3308c2ecf20Sopenharmony_ci		if (!--words)
3318c2ecf20Sopenharmony_ci			goto out;
3328c2ecf20Sopenharmony_ci	}
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
3358c2ecf20Sopenharmony_ci			      : "=d" (res) : "d" (num & -num));
3368c2ecf20Sopenharmony_ci	res ^= 31;
3378c2ecf20Sopenharmony_ciout:
3388c2ecf20Sopenharmony_ci	res += ((long)p - (long)vaddr - 4) * 8;
3398c2ecf20Sopenharmony_ci	return res < size ? res : size;
3408c2ecf20Sopenharmony_ci}
3418c2ecf20Sopenharmony_ci#define find_first_zero_bit find_first_zero_bit
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_cistatic inline int find_next_zero_bit(const unsigned long *vaddr, int size,
3448c2ecf20Sopenharmony_ci				     int offset)
3458c2ecf20Sopenharmony_ci{
3468c2ecf20Sopenharmony_ci	const unsigned long *p = vaddr + (offset >> 5);
3478c2ecf20Sopenharmony_ci	int bit = offset & 31UL, res;
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ci	if (offset >= size)
3508c2ecf20Sopenharmony_ci		return size;
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci	if (bit) {
3538c2ecf20Sopenharmony_ci		unsigned long num = ~*p++ & (~0UL << bit);
3548c2ecf20Sopenharmony_ci		offset -= bit;
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci		/* Look for zero in first longword */
3578c2ecf20Sopenharmony_ci		__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
3588c2ecf20Sopenharmony_ci				      : "=d" (res) : "d" (num & -num));
3598c2ecf20Sopenharmony_ci		if (res < 32) {
3608c2ecf20Sopenharmony_ci			offset += res ^ 31;
3618c2ecf20Sopenharmony_ci			return offset < size ? offset : size;
3628c2ecf20Sopenharmony_ci		}
3638c2ecf20Sopenharmony_ci		offset += 32;
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci		if (offset >= size)
3668c2ecf20Sopenharmony_ci			return size;
3678c2ecf20Sopenharmony_ci	}
3688c2ecf20Sopenharmony_ci	/* No zero yet, search remaining full bytes for a zero */
3698c2ecf20Sopenharmony_ci	return offset + find_first_zero_bit(p, size - offset);
3708c2ecf20Sopenharmony_ci}
3718c2ecf20Sopenharmony_ci#define find_next_zero_bit find_next_zero_bit
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_cistatic inline int find_first_bit(const unsigned long *vaddr, unsigned size)
3748c2ecf20Sopenharmony_ci{
3758c2ecf20Sopenharmony_ci	const unsigned long *p = vaddr;
3768c2ecf20Sopenharmony_ci	int res = 32;
3778c2ecf20Sopenharmony_ci	unsigned int words;
3788c2ecf20Sopenharmony_ci	unsigned long num;
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	if (!size)
3818c2ecf20Sopenharmony_ci		return 0;
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci	words = (size + 31) >> 5;
3848c2ecf20Sopenharmony_ci	while (!(num = *p++)) {
3858c2ecf20Sopenharmony_ci		if (!--words)
3868c2ecf20Sopenharmony_ci			goto out;
3878c2ecf20Sopenharmony_ci	}
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
3908c2ecf20Sopenharmony_ci			      : "=d" (res) : "d" (num & -num));
3918c2ecf20Sopenharmony_ci	res ^= 31;
3928c2ecf20Sopenharmony_ciout:
3938c2ecf20Sopenharmony_ci	res += ((long)p - (long)vaddr - 4) * 8;
3948c2ecf20Sopenharmony_ci	return res < size ? res : size;
3958c2ecf20Sopenharmony_ci}
3968c2ecf20Sopenharmony_ci#define find_first_bit find_first_bit
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_cistatic inline int find_next_bit(const unsigned long *vaddr, int size,
3998c2ecf20Sopenharmony_ci				int offset)
4008c2ecf20Sopenharmony_ci{
4018c2ecf20Sopenharmony_ci	const unsigned long *p = vaddr + (offset >> 5);
4028c2ecf20Sopenharmony_ci	int bit = offset & 31UL, res;
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	if (offset >= size)
4058c2ecf20Sopenharmony_ci		return size;
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_ci	if (bit) {
4088c2ecf20Sopenharmony_ci		unsigned long num = *p++ & (~0UL << bit);
4098c2ecf20Sopenharmony_ci		offset -= bit;
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci		/* Look for one in first longword */
4128c2ecf20Sopenharmony_ci		__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
4138c2ecf20Sopenharmony_ci				      : "=d" (res) : "d" (num & -num));
4148c2ecf20Sopenharmony_ci		if (res < 32) {
4158c2ecf20Sopenharmony_ci			offset += res ^ 31;
4168c2ecf20Sopenharmony_ci			return offset < size ? offset : size;
4178c2ecf20Sopenharmony_ci		}
4188c2ecf20Sopenharmony_ci		offset += 32;
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci		if (offset >= size)
4218c2ecf20Sopenharmony_ci			return size;
4228c2ecf20Sopenharmony_ci	}
4238c2ecf20Sopenharmony_ci	/* No one yet, search remaining full bytes for a one */
4248c2ecf20Sopenharmony_ci	return offset + find_first_bit(p, size - offset);
4258c2ecf20Sopenharmony_ci}
4268c2ecf20Sopenharmony_ci#define find_next_bit find_next_bit
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci/*
4298c2ecf20Sopenharmony_ci * ffz = Find First Zero in word. Undefined if no zero exists,
4308c2ecf20Sopenharmony_ci * so code should check against ~0UL first..
4318c2ecf20Sopenharmony_ci */
4328c2ecf20Sopenharmony_cistatic inline unsigned long ffz(unsigned long word)
4338c2ecf20Sopenharmony_ci{
4348c2ecf20Sopenharmony_ci	int res;
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
4378c2ecf20Sopenharmony_ci			      : "=d" (res) : "d" (~word & -~word));
4388c2ecf20Sopenharmony_ci	return res ^ 31;
4398c2ecf20Sopenharmony_ci}
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_ci#endif
4428c2ecf20Sopenharmony_ci
4438c2ecf20Sopenharmony_ci#include <asm-generic/bitops/find.h>
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci#ifdef __KERNEL__
4468c2ecf20Sopenharmony_ci
4478c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_HAS_NO_BITFIELDS)
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci/*
4508c2ecf20Sopenharmony_ci *	The newer ColdFire family members support a "bitrev" instruction
4518c2ecf20Sopenharmony_ci *	and we can use that to implement a fast ffs. Older Coldfire parts,
4528c2ecf20Sopenharmony_ci *	and normal 68000 parts don't have anything special, so we use the
4538c2ecf20Sopenharmony_ci *	generic functions for those.
4548c2ecf20Sopenharmony_ci */
4558c2ecf20Sopenharmony_ci#if (defined(__mcfisaaplus__) || defined(__mcfisac__)) && \
4568c2ecf20Sopenharmony_ci	!defined(CONFIG_M68000) && !defined(CONFIG_MCPU32)
4578c2ecf20Sopenharmony_cistatic inline unsigned long __ffs(unsigned long x)
4588c2ecf20Sopenharmony_ci{
4598c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("bitrev %0; ff1 %0"
4608c2ecf20Sopenharmony_ci		: "=d" (x)
4618c2ecf20Sopenharmony_ci		: "0" (x));
4628c2ecf20Sopenharmony_ci	return x;
4638c2ecf20Sopenharmony_ci}
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_cistatic inline int ffs(int x)
4668c2ecf20Sopenharmony_ci{
4678c2ecf20Sopenharmony_ci	if (!x)
4688c2ecf20Sopenharmony_ci		return 0;
4698c2ecf20Sopenharmony_ci	return __ffs(x) + 1;
4708c2ecf20Sopenharmony_ci}
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci#else
4738c2ecf20Sopenharmony_ci#include <asm-generic/bitops/ffs.h>
4748c2ecf20Sopenharmony_ci#include <asm-generic/bitops/__ffs.h>
4758c2ecf20Sopenharmony_ci#endif
4768c2ecf20Sopenharmony_ci
4778c2ecf20Sopenharmony_ci#include <asm-generic/bitops/fls.h>
4788c2ecf20Sopenharmony_ci#include <asm-generic/bitops/__fls.h>
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci#else
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_ci/*
4838c2ecf20Sopenharmony_ci *	ffs: find first bit set. This is defined the same way as
4848c2ecf20Sopenharmony_ci *	the libc and compiler builtin ffs routines, therefore
4858c2ecf20Sopenharmony_ci *	differs in spirit from the above ffz (man ffs).
4868c2ecf20Sopenharmony_ci */
4878c2ecf20Sopenharmony_cistatic inline int ffs(int x)
4888c2ecf20Sopenharmony_ci{
4898c2ecf20Sopenharmony_ci	int cnt;
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci	__asm__ ("bfffo %1{#0:#0},%0"
4928c2ecf20Sopenharmony_ci		: "=d" (cnt)
4938c2ecf20Sopenharmony_ci		: "dm" (x & -x));
4948c2ecf20Sopenharmony_ci	return 32 - cnt;
4958c2ecf20Sopenharmony_ci}
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_cistatic inline unsigned long __ffs(unsigned long x)
4988c2ecf20Sopenharmony_ci{
4998c2ecf20Sopenharmony_ci	return ffs(x) - 1;
5008c2ecf20Sopenharmony_ci}
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci/*
5038c2ecf20Sopenharmony_ci *	fls: find last bit set.
5048c2ecf20Sopenharmony_ci */
5058c2ecf20Sopenharmony_cistatic inline int fls(unsigned int x)
5068c2ecf20Sopenharmony_ci{
5078c2ecf20Sopenharmony_ci	int cnt;
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ci	__asm__ ("bfffo %1{#0,#0},%0"
5108c2ecf20Sopenharmony_ci		: "=d" (cnt)
5118c2ecf20Sopenharmony_ci		: "dm" (x));
5128c2ecf20Sopenharmony_ci	return 32 - cnt;
5138c2ecf20Sopenharmony_ci}
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_cistatic inline int __fls(int x)
5168c2ecf20Sopenharmony_ci{
5178c2ecf20Sopenharmony_ci	return fls(x) - 1;
5188c2ecf20Sopenharmony_ci}
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ci#endif
5218c2ecf20Sopenharmony_ci
5228c2ecf20Sopenharmony_ci/* Simple test-and-set bit locks */
5238c2ecf20Sopenharmony_ci#define test_and_set_bit_lock	test_and_set_bit
5248c2ecf20Sopenharmony_ci#define clear_bit_unlock	clear_bit
5258c2ecf20Sopenharmony_ci#define __clear_bit_unlock	clear_bit_unlock
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_ci#include <asm-generic/bitops/ext2-atomic.h>
5288c2ecf20Sopenharmony_ci#include <asm-generic/bitops/le.h>
5298c2ecf20Sopenharmony_ci#include <asm-generic/bitops/fls64.h>
5308c2ecf20Sopenharmony_ci#include <asm-generic/bitops/sched.h>
5318c2ecf20Sopenharmony_ci#include <asm-generic/bitops/hweight.h>
5328c2ecf20Sopenharmony_ci#endif /* __KERNEL__ */
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_ci#endif /* _M68K_BITOPS_H */
535