summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-12-03 11:16:59 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2008-12-03 11:16:59 +1100
commitb032dfc80921daa9c957810fb2e2ff253aaf2ac4 (patch)
treedea437cca9fc39cfdaffd1da99ef24d355ac6818 /lib
parentcf3ff7af2e0be88651723bfbc52afc026b201aef (diff)
bitmap:find_last_bit
Impact: New API As the name suggests. For the moment everyone uses the generic one. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig4
-rw-r--r--lib/Makefile1
-rw-r--r--lib/find_next_bit.c31
3 files changed, 36 insertions, 0 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index 85cf7ea978aa..bfc7b8f33388 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -13,6 +13,10 @@ config GENERIC_FIND_FIRST_BIT
config GENERIC_FIND_NEXT_BIT
bool
+config GENERIC_FIND_LAST_BIT
+ bool
+ default y
+
config CRC_CCITT
tristate "CRC-CCITT functions"
help
diff --git a/lib/Makefile b/lib/Makefile
index 7cb65d85aeb0..cc8335a921e7 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -37,6 +37,7 @@ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o
lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
+lib-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_next_bit.o
obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
obj-$(CONFIG_PLIST) += plist.o
diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c
index 24c59ded47a0..0fc495273924 100644
--- a/lib/find_next_bit.c
+++ b/lib/find_next_bit.c
@@ -159,6 +159,37 @@ found:
EXPORT_SYMBOL(find_first_zero_bit);
#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
+#ifdef CONFIG_GENERIC_FIND_LAST_BIT
+unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
+{
+ unsigned long words;
+ unsigned long tmp;
+
+ /* Start at final word. */
+ words = size / BITS_PER_LONG;
+
+ /* Partial final word? */
+ if (size & (BITS_PER_LONG-1)) {
+ tmp = (addr[words] & (~0UL >> (BITS_PER_LONG
+ - (size & (BITS_PER_LONG-1)))));
+ if (tmp)
+ goto found;
+ }
+
+ while (words) {
+ tmp = addr[--words];
+ if (tmp) {
+found:
+ return words * BITS_PER_LONG + __fls(tmp);
+ }
+ }
+
+ /* Not found */
+ return size;
+}
+EXPORT_SYMBOL(find_last_bit);
+#endif /* CONFIG_GENERIC_FIND_LAST_BIT */
+
#ifdef __BIG_ENDIAN
/* include/linux/byteorder does not support "unsigned long" type */