irqflags.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * interface to Blackfin CEC
  3. *
  4. * Copyright 2009 Analog Devices Inc.
  5. * Licensed under the GPL-2 or later.
  6. */
  7. #ifndef __ASM_BFIN_IRQFLAGS_H__
  8. #define __ASM_BFIN_IRQFLAGS_H__
  9. #include <mach/blackfin.h>
  10. #ifdef CONFIG_SMP
  11. # include <asm/pda.h>
  12. # include <asm/processor.h>
  13. /* Forward decl needed due to cdef inter dependencies */
  14. static inline uint32_t __pure bfin_dspid(void);
  15. # define blackfin_core_id() (bfin_dspid() & 0xff)
  16. # define bfin_irq_flags cpu_pda[blackfin_core_id()].imask
  17. #else
  18. extern unsigned long bfin_irq_flags;
  19. #endif
  20. static inline void bfin_sti(unsigned long flags)
  21. {
  22. asm volatile("sti %0;" : : "d" (flags));
  23. }
  24. static inline unsigned long bfin_cli(void)
  25. {
  26. unsigned long flags;
  27. asm volatile("cli %0;" : "=d" (flags));
  28. return flags;
  29. }
  30. #ifdef CONFIG_DEBUG_HWERR
  31. # define bfin_no_irqs 0x3f
  32. #else
  33. # define bfin_no_irqs 0x1f
  34. #endif
  35. /*****************************************************************************/
  36. /*
  37. * Hard, untraced CPU interrupt flag manipulation and access.
  38. */
  39. static inline void __hard_local_irq_disable(void)
  40. {
  41. bfin_cli();
  42. }
  43. static inline void __hard_local_irq_enable(void)
  44. {
  45. bfin_sti(bfin_irq_flags);
  46. }
  47. static inline unsigned long hard_local_save_flags(void)
  48. {
  49. return bfin_read_IMASK();
  50. }
  51. static inline unsigned long __hard_local_irq_save(void)
  52. {
  53. unsigned long flags;
  54. flags = bfin_cli();
  55. #ifdef CONFIG_DEBUG_HWERR
  56. bfin_sti(0x3f);
  57. #endif
  58. return flags;
  59. }
  60. static inline int hard_irqs_disabled_flags(unsigned long flags)
  61. {
  62. return (flags & ~0x3f) == 0;
  63. }
  64. static inline int hard_irqs_disabled(void)
  65. {
  66. unsigned long flags = hard_local_save_flags();
  67. return hard_irqs_disabled_flags(flags);
  68. }
  69. static inline void __hard_local_irq_restore(unsigned long flags)
  70. {
  71. if (!hard_irqs_disabled_flags(flags))
  72. __hard_local_irq_enable();
  73. }
  74. /*****************************************************************************/
  75. /*
  76. * Interrupt pipe handling.
  77. */
  78. #ifdef CONFIG_IPIPE
  79. #include <linux/compiler.h>
  80. #include <linux/ipipe_base.h>
  81. #include <linux/ipipe_trace.h>
  82. /*
  83. * Interrupt pipe interface to linux/irqflags.h.
  84. */
  85. static inline void arch_local_irq_disable(void)
  86. {
  87. ipipe_check_context(ipipe_root_domain);
  88. __ipipe_stall_root();
  89. barrier();
  90. }
  91. static inline void arch_local_irq_enable(void)
  92. {
  93. barrier();
  94. ipipe_check_context(ipipe_root_domain);
  95. __ipipe_unstall_root();
  96. }
  97. static inline unsigned long arch_local_save_flags(void)
  98. {
  99. return __ipipe_test_root() ? bfin_no_irqs : bfin_irq_flags;
  100. }
  101. static inline int arch_irqs_disabled_flags(unsigned long flags)
  102. {
  103. return flags == bfin_no_irqs;
  104. }
  105. static inline void arch_local_irq_save_ptr(unsigned long *_flags)
  106. {
  107. x = __ipipe_test_and_stall_root() ? bfin_no_irqs : bfin_irq_flags;
  108. barrier();
  109. }
  110. static inline unsigned long arch_local_irq_save(void)
  111. {
  112. ipipe_check_context(ipipe_root_domain);
  113. return __hard_local_irq_save();
  114. }
  115. static inline unsigned long arch_mangle_irq_bits(int virt, unsigned long real)
  116. {
  117. /*
  118. * Merge virtual and real interrupt mask bits into a single
  119. * 32bit word.
  120. */
  121. return (real & ~(1 << 31)) | ((virt != 0) << 31);
  122. }
  123. static inline int arch_demangle_irq_bits(unsigned long *x)
  124. {
  125. int virt = (*x & (1 << 31)) != 0;
  126. *x &= ~(1L << 31);
  127. return virt;
  128. }
  129. /*
  130. * Interface to various arch routines that may be traced.
  131. */
  132. #ifdef CONFIG_IPIPE_TRACE_IRQSOFF
  133. static inline void hard_local_irq_disable(void)
  134. {
  135. if (!hard_irqs_disabled()) {
  136. __hard_local_irq_disable();
  137. ipipe_trace_begin(0x80000000);
  138. }
  139. }
  140. static inline void hard_local_irq_enable(void)
  141. {
  142. if (hard_irqs_disabled()) {
  143. ipipe_trace_end(0x80000000);
  144. __hard_local_irq_enable();
  145. }
  146. }
  147. static inline unsigned long hard_local_irq_save(void)
  148. {
  149. unsigned long flags = hard_local_save_flags();
  150. if (!hard_irqs_disabled_flags(flags)) {
  151. __hard_local_irq_disable();
  152. ipipe_trace_begin(0x80000001);
  153. }
  154. return flags;
  155. }
  156. static inline void hard_local_irq_restore(unsigned long flags)
  157. {
  158. if (!hard_irqs_disabled_flags(flags)) {
  159. ipipe_trace_end(0x80000001);
  160. __hard_local_irq_enable();
  161. }
  162. }
  163. #else /* !CONFIG_IPIPE_TRACE_IRQSOFF */
  164. # define hard_local_irq_disable() __hard_local_irq_disable()
  165. # define hard_local_irq_enable() __hard_local_irq_enable()
  166. # define hard_local_irq_save() __hard_local_irq_save()
  167. # define hard_local_irq_restore(flags) __hard_local_irq_restore(flags)
  168. #endif /* !CONFIG_IPIPE_TRACE_IRQSOFF */
  169. #else /* CONFIG_IPIPE */
  170. /*
  171. * Direct interface to linux/irqflags.h.
  172. */
  173. #define arch_local_save_flags() hard_local_save_flags()
  174. #define arch_local_irq_save(flags) __hard_local_irq_save()
  175. #define arch_local_irq_restore(flags) __hard_local_irq_restore(flags)
  176. #define arch_local_irq_enable() __hard_local_irq_enable()
  177. #define arch_local_irq_disable() __hard_local_irq_disable()
  178. #define arch_irqs_disabled_flags(flags) hard_irqs_disabled_flags(flags)
  179. #define arch_irqs_disabled() hard_irqs_disabled()
  180. /*
  181. * Interface to various arch routines that may be traced.
  182. */
  183. #define hard_local_irq_save() __hard_local_irq_save()
  184. #define hard_local_irq_restore(flags) __hard_local_irq_restore(flags)
  185. #define hard_local_irq_enable() __hard_local_irq_enable()
  186. #define hard_local_irq_disable() __hard_local_irq_disable()
  187. #endif /* !CONFIG_IPIPE */
  188. #endif