irq.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file COPYING in the main directory of this archive
  4. * for more details.
  5. *
  6. * Changed by HuTao Apr18, 2003
  7. *
  8. * Copyright was missing when I got the code so took from MIPS arch ...MaTed---
  9. * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
  10. * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle
  11. *
  12. * Adapted for BlackFin (ADI) by Ted Ma <mated@sympatico.ca>
  13. * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
  14. * Copyright (c) 2002 Lineo, Inc. <mattw@lineo.com>
  15. */
  16. #ifndef _BFIN_IRQ_H_
  17. #define _BFIN_IRQ_H_
  18. /* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h>*/
  19. #include <mach/irq.h>
  20. #include <asm/pda.h>
  21. #include <asm/processor.h>
  22. #ifdef CONFIG_SMP
  23. /* Forward decl needed due to cdef inter dependencies */
  24. static inline uint32_t __pure bfin_dspid(void);
  25. # define blackfin_core_id() (bfin_dspid() & 0xff)
  26. # define bfin_irq_flags cpu_pda[blackfin_core_id()].imask
  27. #else
  28. extern unsigned long bfin_irq_flags;
  29. #endif
  30. #ifdef CONFIG_IPIPE
  31. #include <linux/ipipe_trace.h>
  32. void __ipipe_unstall_root(void);
  33. void __ipipe_restore_root(unsigned long flags);
  34. #ifdef CONFIG_DEBUG_HWERR
  35. # define __all_masked_irq_flags 0x3f
  36. # define __save_and_cli_hw(x) \
  37. __asm__ __volatile__( \
  38. "cli %0;" \
  39. "sti %1;" \
  40. : "=&d"(x) \
  41. : "d" (0x3F) \
  42. )
  43. #else
  44. # define __all_masked_irq_flags 0x1f
  45. # define __save_and_cli_hw(x) \
  46. __asm__ __volatile__( \
  47. "cli %0;" \
  48. : "=&d"(x) \
  49. )
  50. #endif
  51. #define irqs_enabled_from_flags_hw(x) ((x) != __all_masked_irq_flags)
  52. #define raw_irqs_disabled_flags(flags) (!irqs_enabled_from_flags_hw(flags))
  53. #define local_test_iflag_hw(x) irqs_enabled_from_flags_hw(x)
  54. #define local_save_flags(x) \
  55. do { \
  56. (x) = __ipipe_test_root() ? \
  57. __all_masked_irq_flags : bfin_irq_flags; \
  58. barrier(); \
  59. } while (0)
  60. #define local_irq_save(x) \
  61. do { \
  62. (x) = __ipipe_test_and_stall_root() ? \
  63. __all_masked_irq_flags : bfin_irq_flags; \
  64. barrier(); \
  65. } while (0)
  66. static inline void local_irq_restore(unsigned long x)
  67. {
  68. barrier();
  69. __ipipe_restore_root(x == __all_masked_irq_flags);
  70. }
  71. #define local_irq_disable() \
  72. do { \
  73. __ipipe_stall_root(); \
  74. barrier(); \
  75. } while (0)
  76. static inline void local_irq_enable(void)
  77. {
  78. barrier();
  79. __ipipe_unstall_root();
  80. }
  81. #define irqs_disabled() __ipipe_test_root()
  82. #define local_save_flags_hw(x) \
  83. __asm__ __volatile__( \
  84. "cli %0;" \
  85. "sti %0;" \
  86. : "=d"(x) \
  87. )
  88. #define irqs_disabled_hw() \
  89. ({ \
  90. unsigned long flags; \
  91. local_save_flags_hw(flags); \
  92. !irqs_enabled_from_flags_hw(flags); \
  93. })
  94. static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real)
  95. {
  96. /* Merge virtual and real interrupt mask bits into a single
  97. 32bit word. */
  98. return (real & ~(1 << 31)) | ((virt != 0) << 31);
  99. }
  100. static inline int raw_demangle_irq_bits(unsigned long *x)
  101. {
  102. int virt = (*x & (1 << 31)) != 0;
  103. *x &= ~(1L << 31);
  104. return virt;
  105. }
  106. #ifdef CONFIG_IPIPE_TRACE_IRQSOFF
  107. #define local_irq_disable_hw() \
  108. do { \
  109. int _tmp_dummy; \
  110. if (!irqs_disabled_hw()) \
  111. ipipe_trace_begin(0x80000000); \
  112. __asm__ __volatile__ ("cli %0;" : "=d" (_tmp_dummy) : ); \
  113. } while (0)
  114. #define local_irq_enable_hw() \
  115. do { \
  116. if (irqs_disabled_hw()) \
  117. ipipe_trace_end(0x80000000); \
  118. __asm__ __volatile__ ("sti %0;" : : "d"(bfin_irq_flags)); \
  119. } while (0)
  120. #define local_irq_save_hw(x) \
  121. do { \
  122. __save_and_cli_hw(x); \
  123. if (local_test_iflag_hw(x)) \
  124. ipipe_trace_begin(0x80000001); \
  125. } while (0)
  126. #define local_irq_restore_hw(x) \
  127. do { \
  128. if (local_test_iflag_hw(x)) { \
  129. ipipe_trace_end(0x80000001); \
  130. local_irq_enable_hw_notrace(); \
  131. } \
  132. } while (0)
  133. #define local_irq_disable_hw_notrace() \
  134. do { \
  135. int _tmp_dummy; \
  136. __asm__ __volatile__ ("cli %0;" : "=d" (_tmp_dummy) : ); \
  137. } while (0)
  138. #define local_irq_enable_hw_notrace() \
  139. __asm__ __volatile__( \
  140. "sti %0;" \
  141. : \
  142. : "d"(bfin_irq_flags) \
  143. )
  144. #define local_irq_save_hw_notrace(x) __save_and_cli_hw(x)
  145. #define local_irq_restore_hw_notrace(x) \
  146. do { \
  147. if (local_test_iflag_hw(x)) \
  148. local_irq_enable_hw_notrace(); \
  149. } while (0)
  150. #else /* CONFIG_IPIPE_TRACE_IRQSOFF */
  151. #define local_irq_enable_hw() \
  152. __asm__ __volatile__( \
  153. "sti %0;" \
  154. : \
  155. : "d"(bfin_irq_flags) \
  156. )
  157. #define local_irq_disable_hw() \
  158. do { \
  159. int _tmp_dummy; \
  160. __asm__ __volatile__ ( \
  161. "cli %0;" \
  162. : "=d" (_tmp_dummy)); \
  163. } while (0)
  164. #define local_irq_restore_hw(x) \
  165. do { \
  166. if (irqs_enabled_from_flags_hw(x)) \
  167. local_irq_enable_hw(); \
  168. } while (0)
  169. #define local_irq_save_hw(x) __save_and_cli_hw(x)
  170. #define local_irq_disable_hw_notrace() local_irq_disable_hw()
  171. #define local_irq_enable_hw_notrace() local_irq_enable_hw()
  172. #define local_irq_save_hw_notrace(x) local_irq_save_hw(x)
  173. #define local_irq_restore_hw_notrace(x) local_irq_restore_hw(x)
  174. #endif /* CONFIG_IPIPE_TRACE_IRQSOFF */
  175. #else /* !CONFIG_IPIPE */
  176. /*
  177. * Interrupt configuring macros.
  178. */
  179. #define local_irq_disable() \
  180. do { \
  181. int __tmp_dummy; \
  182. __asm__ __volatile__( \
  183. "cli %0;" \
  184. : "=d" (__tmp_dummy) \
  185. ); \
  186. } while (0)
  187. #define local_irq_enable() \
  188. __asm__ __volatile__( \
  189. "sti %0;" \
  190. : \
  191. : "d" (bfin_irq_flags) \
  192. )
  193. #ifdef CONFIG_DEBUG_HWERR
  194. # define __save_and_cli(x) \
  195. __asm__ __volatile__( \
  196. "cli %0;" \
  197. "sti %1;" \
  198. : "=&d" (x) \
  199. : "d" (0x3F) \
  200. )
  201. #else
  202. # define __save_and_cli(x) \
  203. __asm__ __volatile__( \
  204. "cli %0;" \
  205. : "=&d" (x) \
  206. )
  207. #endif
  208. #define local_save_flags(x) \
  209. __asm__ __volatile__( \
  210. "cli %0;" \
  211. "sti %0;" \
  212. : "=d" (x) \
  213. )
  214. #ifdef CONFIG_DEBUG_HWERR
  215. #define irqs_enabled_from_flags(x) (((x) & ~0x3f) != 0)
  216. #else
  217. #define irqs_enabled_from_flags(x) ((x) != 0x1f)
  218. #endif
  219. #define local_irq_restore(x) \
  220. do { \
  221. if (irqs_enabled_from_flags(x)) \
  222. local_irq_enable(); \
  223. } while (0)
  224. /* For spinlocks etc */
  225. #define local_irq_save(x) __save_and_cli(x)
  226. #define irqs_disabled() \
  227. ({ \
  228. unsigned long flags; \
  229. local_save_flags(flags); \
  230. !irqs_enabled_from_flags(flags); \
  231. })
  232. #define local_irq_save_hw(x) local_irq_save(x)
  233. #define local_irq_restore_hw(x) local_irq_restore(x)
  234. #define local_irq_enable_hw() local_irq_enable()
  235. #define local_irq_disable_hw() local_irq_disable()
  236. #define irqs_disabled_hw() irqs_disabled()
  237. #endif /* !CONFIG_IPIPE */
  238. #if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE)
  239. # define NOP_PAD_ANOMALY_05000244 "nop; nop;"
  240. #else
  241. # define NOP_PAD_ANOMALY_05000244
  242. #endif
  243. #define idle_with_irq_disabled() \
  244. __asm__ __volatile__( \
  245. NOP_PAD_ANOMALY_05000244 \
  246. ".align 8;" \
  247. "sti %0;" \
  248. "idle;" \
  249. : \
  250. : "d" (bfin_irq_flags) \
  251. )
  252. static inline int irq_canonicalize(int irq)
  253. {
  254. return irq;
  255. }
  256. #endif /* _BFIN_IRQ_H_ */