blob: c9b21e86977d026415688b9f803ac1c86392d6c9 [file] [log] [blame]
/*
* 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 */