Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5) #include <linux/reciprocal_div.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) #include <linux/minmax.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)  * For a description of the algorithm please have a look at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)  * include/linux/reciprocal_div.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct reciprocal_value reciprocal_value(u32 d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) 	struct reciprocal_value R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) 	u64 m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 	int l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 	l = fls(d - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 	m = ((1ULL << 32) * ((1ULL << l) - d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 	do_div(m, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 	++m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 	R.m = (u32)m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 	R.sh1 = min(l, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 	R.sh2 = max(l - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 	return R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) EXPORT_SYMBOL(reciprocal_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct reciprocal_value_adv reciprocal_value_adv(u32 d, u8 prec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 	struct reciprocal_value_adv R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 	u32 l, post_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 	u64 mhigh, mlow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 	/* ceil(log2(d)) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 	l = fls(d - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 	/* NOTE: mlow/mhigh could overflow u64 when l == 32. This case needs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 	 * be handled before calling "reciprocal_value_adv", please see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 	 * comment at include/linux/reciprocal_div.h.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 	WARN(l == 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 	     "ceil(log2(0x%08x)) == 32, %s doesn't support such divisor",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	     d, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 	post_shift = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 	mlow = 1ULL << (32 + l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 	do_div(mlow, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 	mhigh = (1ULL << (32 + l)) + (1ULL << (32 + l - prec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 	do_div(mhigh, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 	for (; post_shift > 0; post_shift--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 		u64 lo = mlow >> 1, hi = mhigh >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 		if (lo >= hi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 		mlow = lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 		mhigh = hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 	R.m = (u32)mhigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 	R.sh = post_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 	R.exp = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 	R.is_wide_m = mhigh > U32_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 	return R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) EXPORT_SYMBOL(reciprocal_value_adv);