irqflags.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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. static inline unsigned long arch_local_irq_save(void)
  19. {
  20. unsigned long flags;
  21. asm volatile(
  22. " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n"
  23. " cpsid i"
  24. : "=r" (flags) : : "memory", "cc");
  25. return flags;
  26. }
  27. static inline void arch_local_irq_enable(void)
  28. {
  29. asm volatile(
  30. " cpsie i @ arch_local_irq_enable"
  31. :
  32. :
  33. : "memory", "cc");
  34. }
  35. static inline void arch_local_irq_disable(void)
  36. {
  37. asm volatile(
  38. " cpsid i @ arch_local_irq_disable"
  39. :
  40. :
  41. : "memory", "cc");
  42. }
  43. #define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
  44. #define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
  45. #else
  46. /*
  47. * Save the current interrupt enable state & disable IRQs
  48. */
  49. static inline unsigned long arch_local_irq_save(void)
  50. {
  51. unsigned long flags, temp;
  52. asm volatile(
  53. " mrs %0, cpsr @ arch_local_irq_save\n"
  54. " orr %1, %0, #128\n"
  55. " msr cpsr_c, %1"
  56. : "=r" (flags), "=r" (temp)
  57. :
  58. : "memory", "cc");
  59. return flags;
  60. }
  61. /*
  62. * Enable IRQs
  63. */
  64. static inline void arch_local_irq_enable(void)
  65. {
  66. unsigned long temp;
  67. asm volatile(
  68. " mrs %0, cpsr @ arch_local_irq_enable\n"
  69. " bic %0, %0, #128\n"
  70. " msr cpsr_c, %0"
  71. : "=r" (temp)
  72. :
  73. : "memory", "cc");
  74. }
  75. /*
  76. * Disable IRQs
  77. */
  78. static inline void arch_local_irq_disable(void)
  79. {
  80. unsigned long temp;
  81. asm volatile(
  82. " mrs %0, cpsr @ arch_local_irq_disable\n"
  83. " orr %0, %0, #128\n"
  84. " msr cpsr_c, %0"
  85. : "=r" (temp)
  86. :
  87. : "memory", "cc");
  88. }
  89. /*
  90. * Enable FIQs
  91. */
  92. #define local_fiq_enable() \
  93. ({ \
  94. unsigned long temp; \
  95. __asm__ __volatile__( \
  96. "mrs %0, cpsr @ stf\n" \
  97. " bic %0, %0, #64\n" \
  98. " msr cpsr_c, %0" \
  99. : "=r" (temp) \
  100. : \
  101. : "memory", "cc"); \
  102. })
  103. /*
  104. * Disable FIQs
  105. */
  106. #define local_fiq_disable() \
  107. ({ \
  108. unsigned long temp; \
  109. __asm__ __volatile__( \
  110. "mrs %0, cpsr @ clf\n" \
  111. " orr %0, %0, #64\n" \
  112. " msr cpsr_c, %0" \
  113. : "=r" (temp) \
  114. : \
  115. : "memory", "cc"); \
  116. })
  117. #endif
  118. /*
  119. * Save the current interrupt enable state.
  120. */
  121. static inline unsigned long arch_local_save_flags(void)
  122. {
  123. unsigned long flags;
  124. asm volatile(
  125. " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags"
  126. : "=r" (flags) : : "memory", "cc");
  127. return flags;
  128. }
  129. /*
  130. * restore saved IRQ & FIQ state
  131. */
  132. static inline void arch_local_irq_restore(unsigned long flags)
  133. {
  134. asm volatile(
  135. " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore"
  136. :
  137. : "r" (flags)
  138. : "memory", "cc");
  139. }
  140. static inline int arch_irqs_disabled_flags(unsigned long flags)
  141. {
  142. return flags & IRQMASK_I_BIT;
  143. }
  144. #endif /* ifdef __KERNEL__ */
  145. #endif /* ifndef __ASM_ARM_IRQFLAGS_H */