Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __ASM_ARM_IRQFLAGS_H
0003 #define __ASM_ARM_IRQFLAGS_H
0004 
0005 #ifdef __KERNEL__
0006 
0007 #include <asm/ptrace.h>
0008 
0009 /*
0010  * CPU interrupt mask handling.
0011  */
0012 #ifdef CONFIG_CPU_V7M
0013 #define IRQMASK_REG_NAME_R "primask"
0014 #define IRQMASK_REG_NAME_W "primask"
0015 #define IRQMASK_I_BIT   1
0016 #else
0017 #define IRQMASK_REG_NAME_R "cpsr"
0018 #define IRQMASK_REG_NAME_W "cpsr_c"
0019 #define IRQMASK_I_BIT   PSR_I_BIT
0020 #endif
0021 
0022 #if __LINUX_ARM_ARCH__ >= 6
0023 
0024 #define arch_local_irq_save arch_local_irq_save
0025 static inline unsigned long arch_local_irq_save(void)
0026 {
0027     unsigned long flags;
0028 
0029     asm volatile(
0030         "   mrs %0, " IRQMASK_REG_NAME_R "  @ arch_local_irq_save\n"
0031         "   cpsid   i"
0032         : "=r" (flags) : : "memory", "cc");
0033     return flags;
0034 }
0035 
0036 #define arch_local_irq_enable arch_local_irq_enable
0037 static inline void arch_local_irq_enable(void)
0038 {
0039     asm volatile(
0040         "   cpsie i         @ arch_local_irq_enable"
0041         :
0042         :
0043         : "memory", "cc");
0044 }
0045 
0046 #define arch_local_irq_disable arch_local_irq_disable
0047 static inline void arch_local_irq_disable(void)
0048 {
0049     asm volatile(
0050         "   cpsid i         @ arch_local_irq_disable"
0051         :
0052         :
0053         : "memory", "cc");
0054 }
0055 
0056 #define local_fiq_enable()  __asm__("cpsie f    @ __stf" : : : "memory", "cc")
0057 #define local_fiq_disable() __asm__("cpsid f    @ __clf" : : : "memory", "cc")
0058 
0059 #ifndef CONFIG_CPU_V7M
0060 #define local_abt_enable()  __asm__("cpsie a    @ __sta" : : : "memory", "cc")
0061 #define local_abt_disable() __asm__("cpsid a    @ __cla" : : : "memory", "cc")
0062 #else
0063 #define local_abt_enable()  do { } while (0)
0064 #define local_abt_disable() do { } while (0)
0065 #endif
0066 #else
0067 
0068 /*
0069  * Save the current interrupt enable state & disable IRQs
0070  */
0071 #define arch_local_irq_save arch_local_irq_save
0072 static inline unsigned long arch_local_irq_save(void)
0073 {
0074     unsigned long flags, temp;
0075 
0076     asm volatile(
0077         "   mrs %0, cpsr    @ arch_local_irq_save\n"
0078         "   orr %1, %0, #128\n"
0079         "   msr cpsr_c, %1"
0080         : "=r" (flags), "=r" (temp)
0081         :
0082         : "memory", "cc");
0083     return flags;
0084 }
0085 
0086 /*
0087  * Enable IRQs
0088  */
0089 #define arch_local_irq_enable arch_local_irq_enable
0090 static inline void arch_local_irq_enable(void)
0091 {
0092     unsigned long temp;
0093     asm volatile(
0094         "   mrs %0, cpsr    @ arch_local_irq_enable\n"
0095         "   bic %0, %0, #128\n"
0096         "   msr cpsr_c, %0"
0097         : "=r" (temp)
0098         :
0099         : "memory", "cc");
0100 }
0101 
0102 /*
0103  * Disable IRQs
0104  */
0105 #define arch_local_irq_disable arch_local_irq_disable
0106 static inline void arch_local_irq_disable(void)
0107 {
0108     unsigned long temp;
0109     asm volatile(
0110         "   mrs %0, cpsr    @ arch_local_irq_disable\n"
0111         "   orr %0, %0, #128\n"
0112         "   msr cpsr_c, %0"
0113         : "=r" (temp)
0114         :
0115         : "memory", "cc");
0116 }
0117 
0118 /*
0119  * Enable FIQs
0120  */
0121 #define local_fiq_enable()                  \
0122     ({                          \
0123         unsigned long temp;             \
0124     __asm__ __volatile__(                   \
0125     "mrs    %0, cpsr        @ stf\n"        \
0126 "   bic %0, %0, #64\n"                  \
0127 "   msr cpsr_c, %0"                 \
0128     : "=r" (temp)                       \
0129     :                           \
0130     : "memory", "cc");                  \
0131     })
0132 
0133 /*
0134  * Disable FIQs
0135  */
0136 #define local_fiq_disable()                 \
0137     ({                          \
0138         unsigned long temp;             \
0139     __asm__ __volatile__(                   \
0140     "mrs    %0, cpsr        @ clf\n"        \
0141 "   orr %0, %0, #64\n"                  \
0142 "   msr cpsr_c, %0"                 \
0143     : "=r" (temp)                       \
0144     :                           \
0145     : "memory", "cc");                  \
0146     })
0147 
0148 #define local_abt_enable()  do { } while (0)
0149 #define local_abt_disable() do { } while (0)
0150 #endif
0151 
0152 /*
0153  * Save the current interrupt enable state.
0154  */
0155 #define arch_local_save_flags arch_local_save_flags
0156 static inline unsigned long arch_local_save_flags(void)
0157 {
0158     unsigned long flags;
0159     asm volatile(
0160         "   mrs %0, " IRQMASK_REG_NAME_R "  @ local_save_flags"
0161         : "=r" (flags) : : "memory", "cc");
0162     return flags;
0163 }
0164 
0165 /*
0166  * restore saved IRQ & FIQ state
0167  */
0168 #define arch_local_irq_restore arch_local_irq_restore
0169 static inline void arch_local_irq_restore(unsigned long flags)
0170 {
0171     asm volatile(
0172         "   msr " IRQMASK_REG_NAME_W ", %0  @ local_irq_restore"
0173         :
0174         : "r" (flags)
0175         : "memory", "cc");
0176 }
0177 
0178 #define arch_irqs_disabled_flags arch_irqs_disabled_flags
0179 static inline int arch_irqs_disabled_flags(unsigned long flags)
0180 {
0181     return flags & IRQMASK_I_BIT;
0182 }
0183 
0184 #include <asm-generic/irqflags.h>
0185 
0186 #endif /* ifdef __KERNEL__ */
0187 #endif /* ifndef __ASM_ARM_IRQFLAGS_H */