| /* |
| * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de> |
| * |
| * Backport functionality introduced in Linux 3.12. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| |
| #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() |
| */ |
| u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) |
| { |
| /* |
| * 7 extra bytes are necessary to achieve proper functionality |
| * of implement() working on 8 byte chunks |
| */ |
| |
| int len = ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7; |
| |
| 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 */ |