irqflags.h 3.9 KB

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