drm/radeon: Sync to Linux 3.11
[dragonfly.git] / sys / dev / drm / include / linux / math64.h
CommitLineData
563a794d
FT
1/*-
2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2014 Mellanox Technologies, Ltd. All rights reserved.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef _LINUX_MATH64_H
29#define _LINUX_MATH64_H
30
31#include <linux/types.h>
32#include <linux/bitops.h>
33
34#if BITS_PER_LONG == 64
35
36# define do_div(n, base) ({ \
37 uint32_t __base = (base); \
38 uint32_t __rem; \
39 __rem = ((uint64_t)(n)) % __base; \
40 (n) = ((uint64_t)(n)) / __base; \
41 __rem; \
42})
43
44/**
45* div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder
46*
47* This is commonly provided by 32bit archs to provide an optimized 64bit
48* divide.
49*/
50static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
51{
57e252bf
MN
52 *remainder = dividend % divisor;
53 return dividend / divisor;
563a794d
FT
54}
55
57e252bf
MN
56/**
57 * div64_u64 - unsigned 64bit divide with 64bit divisor
58 */
59static inline u64 div64_u64(u64 dividend, u64 divisor)
60{
61 return dividend / divisor;
62}
63
64/**
65 * div64_s64 - signed 64bit divide with 64bit divisor
66 */
67static inline s64 div64_s64(s64 dividend, s64 divisor)
68{
69 return dividend / divisor;
70}
563a794d
FT
71
72#elif BITS_PER_LONG == 32
73
74static uint32_t __div64_32(uint64_t *n, uint32_t base)
75{
76 uint64_t rem = *n;
77 uint64_t b = base;
78 uint64_t res, d = 1;
79 uint32_t high = rem >> 32;
80
81 /* Reduce the thing a bit first */
82 res = 0;
83 if (high >= base) {
84 high /= base;
85 res = (uint64_t) high << 32;
86 rem -= (uint64_t) (high*base) << 32;
87 }
88
89 while ((int64_t)b > 0 && b < rem) {
90 b = b+b;
91 d = d+d;
92 }
93
94 do {
95 if (rem >= b) {
96 rem -= b;
97 res += d;
98 }
99 b >>= 1;
100 d >>= 1;
101 } while (d);
102
103 *n = res;
104 return rem;
105}
106
107# define do_div(n, base) ({ \
108 uint32_t __base = (base); \
109 uint32_t __rem; \
110 (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \
111 if (likely(((n) >> 32) == 0)) { \
112 __rem = (uint32_t)(n) % __base; \
113 (n) = (uint32_t)(n) / __base; \
114 } else \
115 __rem = __div64_32(&(n), __base); \
116 __rem; \
117})
118
119#ifndef div_u64_rem
120static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
121{
122 *remainder = do_div(dividend, divisor);
123 return dividend;
124}
125#endif
126
127#endif /* BITS_PER_LONG */
128
129
130
131/**
132 ** div_u64 - unsigned 64bit divide with 32bit divisor
133 **
134 ** This is the most common 64bit divide and should be used if possible,
135 ** as many 32bit archs can optimize this variant better than a full 64bit
136 ** divide.
137 * */
138#ifndef div_u64
139
140static inline u64 div_u64(u64 dividend, u32 divisor)
141{
142 u32 remainder;
143 return div_u64_rem(dividend, divisor, &remainder);
144}
145#endif
146
147#endif /* _LINUX_MATH64_H */