support.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * =====================================================================================
  3. *
  4. * Filename: support.h
  5. *
  6. * Description: misc utilities definition.
  7. *
  8. * Version: 2.0
  9. * Create: 2017-11-03 11:34:34
  10. * Revision: none
  11. * Compiler: gcc version 6.3.0 (crosstool-NG crosstool-ng-1.23.0)
  12. *
  13. * Author: caozilong@allwinnertech.com
  14. * Organization: BU1-PSW
  15. * Last Modified: 2020-03-25 12:20:13
  16. *
  17. * =====================================================================================
  18. */
  19. #ifndef __SUPPORT_H__
  20. #define __SUPPORT_H__
  21. #include <typedef.h>
  22. #include <kapi.h>
  23. /*
  24. * Generic macro to convert pointers to values for comparison purposes.
  25. */
  26. #ifndef p2n
  27. #define p2n(p) ((ptrdiff_t)((ptrdiff_t*)(p)))
  28. #endif
  29. /*
  30. * min()/max() macros that also do
  31. * strict type-checking.. See the
  32. * "unnecessary" pointer comparison.
  33. */
  34. #ifndef min
  35. #define min(x,y) ({ \
  36. typeof(x) _x = (x); \
  37. typeof(y) _y = (y); \
  38. (void) (&_x == &_y); \
  39. _x < _y ? _x : _y; })
  40. #endif
  41. #ifndef max
  42. #define max(x,y) ({ \
  43. typeof(x) _x = (x); \
  44. typeof(y) _y = (y); \
  45. (void) (&_x == &_y); \
  46. _x > _y ? _x : _y; })
  47. #endif
  48. /*
  49. * ..and if you can't take the strict
  50. * types, you can specify one yourself.
  51. *
  52. * Or not use min/max at all, of course.
  53. */
  54. #define min_t(type,x,y) \
  55. ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
  56. #define max_t(type,x,y) \
  57. ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
  58. //#define BITS_PER_LONG 32
  59. //#define BITS_PER_LONG_LONG 64
  60. #ifndef ALIGN
  61. #define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
  62. #endif
  63. #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
  64. #ifndef INT_MAX
  65. #define INT_MAX ((int)(~0U>>1))
  66. #endif
  67. #ifndef INT_MIN
  68. #define INT_MIN (-INT_MAX - 1)
  69. #endif
  70. #ifndef UINT_MAX
  71. #define UINT_MAX (~0U)
  72. #endif
  73. #ifndef LONG_MAX
  74. #define LONG_MAX ((long)(~0UL>>1))
  75. #endif
  76. #ifndef LONG_MIN
  77. #define LONG_MIN (-LONG_MAX - 1)
  78. #endif
  79. #ifndef ULONG_MAX
  80. #define ULONG_MAX (~0UL)
  81. #endif
  82. #ifndef LLONG_MAX
  83. #define LLONG_MAX ((long long)(~0ULL>>1))
  84. #endif
  85. #ifndef LLONG_MIN
  86. #define LLONG_MIN (-LLONG_MAX - 1)
  87. #endif
  88. #ifndef ULLONG_MAX
  89. #define ULLONG_MAX (~0ULL)
  90. #endif
  91. #ifndef DATA_TYPE_X_BOOL
  92. #define DATA_TYPE_X_BOOL
  93. typedef enum
  94. {
  95. #ifndef FALSE
  96. FALSE = 0,
  97. #endif
  98. #ifndef NO
  99. NO = 0,
  100. #endif
  101. #ifndef ZERO
  102. ZERO = 0,
  103. #endif
  104. #ifndef TRUE
  105. TRUE = 1,
  106. #endif
  107. #ifndef YES
  108. YES = 1,
  109. #endif
  110. #ifndef ONE
  111. ONE = 1,
  112. #endif
  113. #ifndef OK
  114. OK = 0,
  115. #endif
  116. #ifndef FAIL
  117. FAIL = -1,
  118. #endif
  119. } BOOL;
  120. #endif
  121. /*
  122. * Check at compile time that something is of a particular type.
  123. * Always evaluates to 1 so you may use it easily in comparisons.
  124. */
  125. #define typecheck(type,x) \
  126. ({ type __dummy; \
  127. typeof(x) __dummy2; \
  128. (void)(&__dummy == &__dummy2); \
  129. 1; \
  130. })
  131. static inline int is_power_of_2(unsigned long n)
  132. {
  133. return (n != 0 && ((n & (n - 1)) == 0));
  134. }
  135. /* round "x" up/down to next multiple of "align" (which must be a power of 2) */
  136. #define ROUND_UP(x, align) \
  137. (((unsigned long)(x) + ((unsigned long)(align) - 1)) & \
  138. ~((unsigned long)(align) - 1))
  139. #define ROUND_DOWN(x, align) \
  140. ((unsigned long)(x) & ~((unsigned long)(align) - 1))
  141. //#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
  142. /**
  143. * test_bit - Determine whether a bit is set
  144. * @nr: bit number to test
  145. * @addr: Address to start counting from
  146. */
  147. static inline int test_bit(int nr, long *addr)
  148. {
  149. int mask;
  150. addr += nr >> 5;
  151. mask = 1 << (nr & 0x1f);
  152. return ((mask & *addr) != 0);
  153. }
  154. /*
  155. * These functions are the basis of our bit ops.
  156. *
  157. * First, the atomic bitops. These use native endian.
  158. */
  159. static inline void set_bit(unsigned int bit, volatile unsigned long *p)
  160. {
  161. unsigned long flags;
  162. unsigned long mask = 1UL << (bit & 31);
  163. p += bit >> 5;
  164. ENTER_CRITICAL(flags);
  165. *p |= mask;
  166. EXIT_CRITICAL(flags);
  167. }
  168. static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
  169. {
  170. unsigned long flags;
  171. unsigned long mask = 1UL << (bit & 31);
  172. p += bit >> 5;
  173. ENTER_CRITICAL(flags);
  174. *p &= ~mask;
  175. EXIT_CRITICAL(flags);
  176. }
  177. static inline void change_bit(unsigned int bit, volatile unsigned long *p)
  178. {
  179. unsigned long flags;
  180. unsigned long mask = 1UL << (bit & 31);
  181. p += bit >> 5;
  182. ENTER_CRITICAL(flags);
  183. *p ^= mask;
  184. EXIT_CRITICAL(flags);
  185. }
  186. static inline int test_and_set_bit(unsigned int bit, volatile unsigned long *p)
  187. {
  188. unsigned long flags;
  189. unsigned int res;
  190. unsigned long mask = 1UL << (bit & 31);
  191. p += bit >> 5;
  192. ENTER_CRITICAL(flags);
  193. res = *p;
  194. *p = res | mask;
  195. EXIT_CRITICAL(flags);
  196. return res & mask;
  197. }
  198. static inline int test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
  199. {
  200. unsigned long flags;
  201. unsigned int res;
  202. unsigned long mask = 1UL << (bit & 31);
  203. p += bit >> 5;
  204. ENTER_CRITICAL(flags);
  205. res = *p;
  206. *p = res & ~mask;
  207. EXIT_CRITICAL(flags);
  208. return res & mask;
  209. }
  210. static inline int test_and_change_bit(unsigned int bit, volatile unsigned long *p)
  211. {
  212. unsigned long flags;
  213. unsigned int res;
  214. unsigned long mask = 1UL << (bit & 31);
  215. p += bit >> 5;
  216. ENTER_CRITICAL(flags);
  217. res = *p;
  218. *p = res ^ mask;
  219. EXIT_CRITICAL(flags);
  220. return res & mask;
  221. }
  222. /* -------------------------------- jiffies -----------------------------*/
  223. #define HZ 100
  224. #define jiffies ((unsigned long)rt_tick_get())
  225. /*
  226. * These inlines deal with timer wrapping correctly. You are
  227. * strongly encouraged to use them
  228. * 1. Because people otherwise forget
  229. * 2. Because if the timer wrap changes in future you won't have to
  230. * alter your driver code.
  231. *
  232. * time_after(a,b) returns true if the time a is after time b.
  233. *
  234. * Do this with "<0" and ">=0" to only test the sign of the result. A
  235. * good compiler would generate better code (and a really good compiler
  236. * wouldn't care). Gcc is currently neither.
  237. */
  238. #define time_after(a,b) \
  239. (typecheck(unsigned long, a) && \
  240. typecheck(unsigned long, b) && \
  241. ((int)(b) - (int)(a) < 0))
  242. #define time_before(a,b) time_after(b,a)
  243. #define time_after_eq(a,b) \
  244. (typecheck(unsigned long, a) && \
  245. typecheck(unsigned long, b) && \
  246. ((int)(a) - (int)(b) >= 0))
  247. #define time_before_eq(a,b) time_after_eq(b,a)
  248. #endif /* __SUPPORT_H__ */