This function was added to the mainline kernel in commit eb18cba7 "math64: New separate div64_u64_rem helper" and is now used the virtual video test driver. Signed-off-by: Hauke Mehrtens <hauke@xxxxxxxxxx> --- backport/backport-include/linux/math64.h | 27 ++++++++++++++++++++ backport/compat/backport-3.12.c | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 backport/backport-include/linux/math64.h diff --git a/backport/backport-include/linux/math64.h b/backport/backport-include/linux/math64.h new file mode 100644 index 0000000..2fbde06 --- /dev/null +++ b/backport/backport-include/linux/math64.h @@ -0,0 +1,27 @@ +#ifndef __BACKPORT_LINUX_MATH64_H +#define __BACKPORT_LINUX_MATH64_H +#include_next <linux/math64.h> + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) + +#if BITS_PER_LONG == 64 +/** + * div64_u64_rem - unsigned 64bit divide with 64bit divisor and remainder + */ +#define div64_u64_rem LINUX_BACKPORT(div64_u64_rem) +static inline u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder) +{ + *remainder = dividend % divisor; + return dividend / divisor; +} +#elif BITS_PER_LONG == 32 +#ifndef div64_u64_rem +#define div64_u64_rem LINUX_BACKPORT(div64_u64_rem) +#define backports_div64_u64_rem_add 1 +extern u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder); +#endif + +#endif /* BITS_PER_LONG */ +#endif /* < 3.12 */ + +#endif /* __BACKPORT_LINUX_MATH64_H */ diff --git a/backport/compat/backport-3.12.c b/backport/compat/backport-3.12.c index 7e3dc58..c9b21e8 100644 --- a/backport/compat/backport-3.12.c +++ b/backport/compat/backport-3.12.c @@ -11,6 +11,7 @@ #include <linux/export.h> #include <linux/hid.h> #include <linux/bug.h> +#include <linux/math64.h> /* * Allocator for buffer that is going to be passed to hid_output_report() @@ -27,3 +28,45 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) return kmalloc(len, flags); } EXPORT_SYMBOL_GPL(hid_alloc_report_buf); + +#if BITS_PER_LONG == 32 +/** + * div64_u64_rem - unsigned 64bit divide with 64bit divisor and remainder + * @dividend: 64bit dividend + * @divisor: 64bit divisor + * @remainder: 64bit remainder + * + * This implementation is a comparable to algorithm used by div64_u64. + * But this operation, which includes math for calculating the remainder, + * is kept distinct to avoid slowing down the div64_u64 operation on 32bit + * systems. + */ +#ifndef backports_div64_u64_rem_add +u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder) +{ + u32 high = divisor >> 32; + u64 quot; + + if (high == 0) { + u32 rem32; + quot = div_u64_rem(dividend, divisor, &rem32); + *remainder = rem32; + } else { + int n = 1 + fls(high); + quot = div_u64(dividend >> n, divisor >> n); + + if (quot != 0) + quot--; + + *remainder = dividend - quot * divisor; + if (*remainder >= divisor) { + quot++; + *remainder -= divisor; + } + } + + return quot; +} +EXPORT_SYMBOL_GPL(div64_u64_rem); +#endif /* backports_div64_u64_rem_add */ +#endif /* BITS_PER_LONG */ -- 2.7.0 -- To unsubscribe from this list: send the line "unsubscribe backports" in