irqflags.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. #else
  49. /*
  50. * Save the current interrupt enable state & disable IRQs
  51. */
  52. #define arch_local_irq_save arch_local_irq_save
  53. static inline unsigned long arch_local_irq_save(void)
  54. {
  55. unsigned long flags, temp;
  56. asm volatile(
  57. " mrs %0, cpsr @ arch_local_irq_save\n"
  58. " orr %1, %0, #128\n"
  59. " msr cpsr_c, %1"
  60. : "=r" (flags), "=r" (temp)
  61. :
  62. : "memory", "cc");
  63. return flags;
  64. }
  65. /*
  66. * Enable IRQs
  67. */
  68. #define arch_local_irq_enable arch_local_irq_enable
  69. static inline void arch_local_irq_enable(void)
  70. {
  71. unsigned long temp;
  72. asm volatile(
  73. " mrs %0, cpsr @ arch_local_irq_enable\n"
  74. " bic %0, %0, #128\n"
  75. " msr cpsr_c, %0"
  76. : "=r" (temp)
  77. :
  78. : "memory", "cc");
  79. }
  80. /*
  81. * Disable IRQs
  82. */
  83. #define arch_local_irq_disable arch_local_irq_disable
  84. static inline void arch_local_irq_disable(void)
  85. {
  86. unsigned long temp;
  87. asm volatile(
  88. " mrs %0, cpsr @ arch_local_irq_disable\n"
  89. " orr %0, %0, #128\n"
  90. " msr cpsr_c, %0"
  91. : "=r" (temp)
  92. :
  93. : "memory", "cc");
  94. }
  95. /*
  96. * Enable FIQs
  97. */
  98. #define local_fiq_enable() \
  99. ({ \
  100. unsigned long temp; \
  101. __asm__ __volatile__( \
  102. "mrs %0, cpsr @ stf\n" \
  103. " bic %0, %0, #64\n" \
  104. " msr cpsr_c, %0" \
  105. : "=r" (temp) \
  106. : \
  107. : "memory", "cc"); \
  108. })
  109. /*
  110. * Disable FIQs
  111. */
  112. #define local_fiq_disable() \
  113. ({ \
  114. unsigned long temp; \
  115. __asm__ __volatile__( \
  116. "mrs %0, cpsr @ clf\n" \
  117. " orr %0, %0, #64\n" \
  118. " msr cpsr_c, %0" \
  119. : "=r" (temp) \
  120. : \
  121. : "memory", "cc"); \
  122. })
  123. #endif
  124. /*
  125. * Save the current interrupt enable state.
  126. */
  127. #define arch_local_save_flags arch_local_save_flags
  128. static inline unsigned long arch_local_save_flags(void)
  129. {
  130. unsigned long flags;
  131. asm volatile(
  132. " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags"
  133. : "=r" (flags) : : "memory", "cc");
  134. return flags;
  135. }
  136. /*
  137. * restore saved IRQ & FIQ state
  138. */
  139. #define arch_local_irq_restore arch_local_irq_restore
  140. static inline void arch_local_irq_restore(unsigned long flags)
  141. {
  142. asm volatile(
  143. " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore"
  144. :
  145. : "r" (flags)
  146. : "memory", "cc");
  147. }
  148. #define arch_irqs_disabled_flags arch_irqs_disabled_flags
  149. static inline int arch_irqs_disabled_flags(unsigned long flags)
  150. {
  151. return flags & IRQMASK_I_BIT;
  152. }
  153. #include <asm-generic/irqflags.h>
  154. #endif /* ifdef __KERNEL__ */
  155. #endif /* ifndef __ASM_ARM_IRQFLAGS_H */