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