irqflags.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #ifndef __ASM_ARM_IRQFLAGS_H
  2. #define __ASM_ARM_IRQFLAGS_H
  3. #ifdef __KERNEL__
  4. #include <asm/ptrace.h>
  5. /*
  6. * CPU interrupt mask handling.
  7. */
  8. #ifdef CONFIG_CPU_V7M
  9. #define IRQMASK_REG_NAME_R "primask"
  10. #define IRQMASK_REG_NAME_W "primask"
  11. #define IRQMASK_I_BIT 1
  12. #else
  13. #define IRQMASK_REG_NAME_R "cpsr"
  14. #define IRQMASK_REG_NAME_W "cpsr_c"
  15. #define IRQMASK_I_BIT PSR_I_BIT
  16. #endif
  17. #if __LINUX_ARM_ARCH__ >= 6
  18. #define arch_local_irq_save arch_local_irq_save
  19. static inline unsigned long arch_local_irq_save(void)
  20. {
  21. unsigned long flags;
  22. asm volatile(
  23. " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n"
  24. " cpsid i"
  25. : "=r" (flags) : : "memory", "cc");
  26. return flags;
  27. }
  28. #define arch_local_irq_enable arch_local_irq_enable
  29. static inline void arch_local_irq_enable(void)
  30. {
  31. asm volatile(
  32. " cpsie i @ arch_local_irq_enable"
  33. :
  34. :
  35. : "memory", "cc");
  36. }
  37. #define arch_local_irq_disable arch_local_irq_disable
  38. static inline void arch_local_irq_disable(void)
  39. {
  40. asm volatile(
  41. " cpsid i @ arch_local_irq_disable"
  42. :
  43. :
  44. : "memory", "cc");
  45. }
  46. #define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
  47. #define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
  48. #ifndef CONFIG_CPU_V7M
  49. #define local_abt_enable() __asm__("cpsie a @ __sta" : : : "memory", "cc")
  50. #define local_abt_disable() __asm__("cpsid a @ __cla" : : : "memory", "cc")
  51. #else
  52. #define local_abt_enable() do { } while (0)
  53. #define local_abt_disable() do { } while (0)
  54. #endif
  55. #else
  56. /*
  57. * Save the current interrupt enable state & disable IRQs
  58. */
  59. #define arch_local_irq_save arch_local_irq_save
  60. static inline unsigned long arch_local_irq_save(void)
  61. {
  62. unsigned long flags, temp;
  63. asm volatile(
  64. " mrs %0, cpsr @ arch_local_irq_save\n"
  65. " orr %1, %0, #128\n"
  66. " msr cpsr_c, %1"
  67. : "=r" (flags), "=r" (temp)
  68. :
  69. : "memory", "cc");
  70. return flags;
  71. }
  72. /*
  73. * Enable IRQs
  74. */
  75. #define arch_local_irq_enable arch_local_irq_enable
  76. static inline void arch_local_irq_enable(void)
  77. {
  78. unsigned long temp;
  79. asm volatile(
  80. " mrs %0, cpsr @ arch_local_irq_enable\n"
  81. " bic %0, %0, #128\n"
  82. " msr cpsr_c, %0"
  83. : "=r" (temp)
  84. :
  85. : "memory", "cc");
  86. }
  87. /*
  88. * Disable IRQs
  89. */
  90. #define arch_local_irq_disable arch_local_irq_disable
  91. static inline void arch_local_irq_disable(void)
  92. {
  93. unsigned long temp;
  94. asm volatile(
  95. " mrs %0, cpsr @ arch_local_irq_disable\n"
  96. " orr %0, %0, #128\n"
  97. " msr cpsr_c, %0"
  98. : "=r" (temp)
  99. :
  100. : "memory", "cc");
  101. }
  102. /*
  103. * Enable FIQs
  104. */
  105. #define local_fiq_enable() \
  106. ({ \
  107. unsigned long temp; \
  108. __asm__ __volatile__( \
  109. "mrs %0, cpsr @ stf\n" \
  110. " bic %0, %0, #64\n" \
  111. " msr cpsr_c, %0" \
  112. : "=r" (temp) \
  113. : \
  114. : "memory", "cc"); \
  115. })
  116. /*
  117. * Disable FIQs
  118. */
  119. #define local_fiq_disable() \
  120. ({ \
  121. unsigned long temp; \
  122. __asm__ __volatile__( \
  123. "mrs %0, cpsr @ clf\n" \
  124. " orr %0, %0, #64\n" \
  125. " msr cpsr_c, %0" \
  126. : "=r" (temp) \
  127. : \
  128. : "memory", "cc"); \
  129. })
  130. #define local_abt_enable() do { } while (0)
  131. #define local_abt_disable() do { } while (0)
  132. #endif
  133. /*
  134. * Save the current interrupt enable state.
  135. */
  136. #define arch_local_save_flags arch_local_save_flags
  137. static inline unsigned long arch_local_save_flags(void)
  138. {
  139. unsigned long flags;
  140. asm volatile(
  141. " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags"
  142. : "=r" (flags) : : "memory", "cc");
  143. return flags;
  144. }
  145. /*
  146. * restore saved IRQ & FIQ state
  147. */
  148. #define arch_local_irq_restore arch_local_irq_restore
  149. static inline void arch_local_irq_restore(unsigned long flags)
  150. {
  151. asm volatile(
  152. " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore"
  153. :
  154. : "r" (flags)
  155. : "memory", "cc");
  156. }
  157. #define arch_irqs_disabled_flags arch_irqs_disabled_flags
  158. static inline int arch_irqs_disabled_flags(unsigned long flags)
  159. {
  160. return flags & IRQMASK_I_BIT;
  161. }
  162. #include <asm-generic/irqflags.h>
  163. #endif /* ifdef __KERNEL__ */
  164. #endif /* ifndef __ASM_ARM_IRQFLAGS_H */