Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
[pandora-kernel.git] / include / asm-generic / page.h
1 #ifndef _ASM_GENERIC_PAGE_H
2 #define _ASM_GENERIC_PAGE_H
3
4 #ifdef __KERNEL__
5 #ifndef __ASSEMBLY__
6
7 #include <linux/log2.h>
8
9 /*
10  * non-const pure 2^n version of get_order
11  * - the arch may override these in asm/bitops.h if they can be implemented
12  *   more efficiently than using the arch log2 routines
13  * - we use the non-const log2() instead if the arch has defined one suitable
14  */
15 #ifndef ARCH_HAS_GET_ORDER
16 static inline __attribute__((const))
17 int __get_order(unsigned long size, int page_shift)
18 {
19 #if BITS_PER_LONG == 32 && defined(ARCH_HAS_ILOG2_U32)
20         int order = __ilog2_u32(size) - page_shift;
21         return order >= 0 ? order : 0;
22 #elif BITS_PER_LONG == 64 && defined(ARCH_HAS_ILOG2_U64)
23         int order = __ilog2_u64(size) - page_shift;
24         return order >= 0 ? order : 0;
25 #else
26         int order;
27
28         size = (size - 1) >> (page_shift - 1);
29         order = -1;
30         do {
31                 size >>= 1;
32                 order++;
33         } while (size);
34         return order;
35 #endif
36 }
37 #endif
38
39 /**
40  * get_order - calculate log2(pages) to hold a block of the specified size
41  * @n - size
42  *
43  * calculate allocation order based on the current page size
44  * - this can be used to initialise global variables from constant data
45  */
46 #define get_order(n)                                                    \
47 (                                                                       \
48         __builtin_constant_p(n) ?                                       \
49         ((n < (1UL << PAGE_SHIFT)) ? 0 : ilog2(n) - PAGE_SHIFT) :       \
50         __get_order(n, PAGE_SHIFT)                                      \
51  )
52
53 #endif  /* __ASSEMBLY__ */
54 #endif  /* __KERNEL__ */
55
56 #endif  /* _ASM_GENERIC_PAGE_H */