summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-03-26 06:54:23 +0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 09:23:33 +0400
commit3927f2e8f9afa3424bb51ca81f7abac01ffd0005 (patch)
treeda9e335169572e6c743c084edce6a802f9e667ee /lib
parent9d729f72dca9406025bcfa9c1f660d71d9ef0ff5 (diff)
downloadlinux-3927f2e8f9afa3424bb51ca81f7abac01ffd0005.tar.xz
[NET]: div64_64 consolidate (rev3)
Here is the current version of the 64 bit divide common code. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile5
-rw-r--r--lib/div64.c22
2 files changed, 25 insertions, 2 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 992a39ef9ffd..ae57f357fec0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -4,7 +4,7 @@
lib-y := ctype.o string.o vsprintf.o cmdline.o \
rbtree.o radix-tree.o dump_stack.o \
- idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
+ idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \
sha1.o irq_regs.o reciprocal_div.o
lib-$(CONFIG_MMU) += ioremap.o
@@ -12,7 +12,8 @@ lib-$(CONFIG_SMP) += cpumask.o
lib-y += kobject.o kref.o kobject_uevent.o klist.o
-obj-y += sort.o parser.o halfmd4.o debug_locks.o random32.o bust_spinlocks.o
+obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
+ bust_spinlocks.o
ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
diff --git a/lib/div64.c b/lib/div64.c
index 365719f84832..c3d7655cdfb5 100644
--- a/lib/div64.c
+++ b/lib/div64.c
@@ -58,4 +58,26 @@ uint32_t __div64_32(uint64_t *n, uint32_t base)
EXPORT_SYMBOL(__div64_32);
+/* 64bit divisor, dividend and result. dynamic precision */
+uint64_t div64_64(uint64_t dividend, uint64_t divisor)
+{
+ uint32_t d = divisor;
+
+ if (divisor > 0xffffffffULL) {
+ unsigned int shift = fls(divisor >> 32);
+
+ d = divisor >> shift;
+ dividend >>= shift;
+ }
+
+ /* avoid 64 bit division if possible */
+ if (dividend >> 32)
+ do_div(dividend, d);
+ else
+ dividend = (uint32_t) dividend / d;
+
+ return dividend;
+}
+EXPORT_SYMBOL(div64_64);
+
#endif /* BITS_PER_LONG == 32 */