linux/arch/arm/include/asm/irqflags.h
<<
>>
Prefs
   1#ifndef __ASM_ARM_IRQFLAGS_H
   2#define __ASM_ARM_IRQFLAGS_H
   3
   4#ifdef __KERNEL__
   5
   6#include <asm/ptrace.h>
   7
   8/*
   9 * CPU interrupt mask handling.
  10 */
  11#ifdef CONFIG_CPU_V7M
  12#define IRQMASK_REG_NAME_R "primask"
  13#define IRQMASK_REG_NAME_W "primask"
  14#define IRQMASK_I_BIT   1
  15#else
  16#define IRQMASK_REG_NAME_R "cpsr"
  17#define IRQMASK_REG_NAME_W "cpsr_c"
  18#define IRQMASK_I_BIT   PSR_I_BIT
  19#endif
  20
  21#if __LINUX_ARM_ARCH__ >= 6
  22
  23static inline unsigned long arch_local_irq_save(void)
  24{
  25        unsigned long flags;
  26
  27        asm volatile(
  28                "       mrs     %0, " IRQMASK_REG_NAME_R "      @ arch_local_irq_save\n"
  29                "       cpsid   i"
  30                : "=r" (flags) : : "memory", "cc");
  31        return flags;
  32}
  33
  34static inline void arch_local_irq_enable(void)
  35{
  36        asm volatile(
  37                "       cpsie i                 @ arch_local_irq_enable"
  38                :
  39                :
  40                : "memory", "cc");
  41}
  42
  43static inline void arch_local_irq_disable(void)
  44{
  45        asm volatile(
  46                "       cpsid i                 @ arch_local_irq_disable"
  47                :
  48                :
  49                : "memory", "cc");
  50}
  51
  52#define local_fiq_enable()  __asm__("cpsie f    @ __stf" : : : "memory", "cc")
  53#define local_fiq_disable() __asm__("cpsid f    @ __clf" : : : "memory", "cc")
  54#else
  55
  56/*
  57 * Save the current interrupt enable state & disable IRQs
  58 */
  59static inline unsigned long arch_local_irq_save(void)
  60{
  61        unsigned long flags, temp;
  62
  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/*
  74 * Enable IRQs
  75 */
  76static 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/*
  89 * Disable IRQs
  90 */
  91static 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/*
 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/*
 119 * Disable FIQs
 120 */
 121#define local_fiq_disable()                                     \
 122        ({                                                      \
 123                unsigned long temp;                             \
 124        __asm__ __volatile__(                                   \
 125        "mrs    %0, cpsr                @ clf\n"                \
 126"       orr     %0, %0, #64\n"                                  \
 127"       msr     cpsr_c, %0"                                     \
 128        : "=r" (temp)                                           \
 129        :                                                       \
 130        : "memory", "cc");                                      \
 131        })
 132
 133#endif
 134
 135/*
 136 * Save the current interrupt enable state.
 137 */
 138static 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/*
 148 * restore saved IRQ & FIQ state
 149 */
 150static 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
 159static inline int arch_irqs_disabled_flags(unsigned long flags)
 160{
 161        return flags & IRQMASK_I_BIT;
 162}
 163
 164#endif /* ifdef __KERNEL__ */
 165#endif /* ifndef __ASM_ARM_IRQFLAGS_H */
 166