1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * IRQ flags handling 4 * 5 * This file gets included from lowlevel asm headers too, to provide 6 * wrapped versions of the local_irq_*() APIs, based on the 7 * raw_local_irq_*() functions from the lowlevel headers. 8 */ 9 #ifndef _ASM_IRQFLAGS_H 10 #define _ASM_IRQFLAGS_H 11 12 #ifndef __ASSEMBLY__ 13 14 #include <asm/core_reg.h> 15 #include <asm/metag_regs.h> 16 17 #define INTS_OFF_MASK TXSTATI_BGNDHALT_BIT 18 19 #ifdef CONFIG_SMP 20 extern unsigned int get_trigger_mask(void); 21 #else 22 23 extern unsigned int global_trigger_mask; 24 get_trigger_mask(void)25 static inline unsigned int get_trigger_mask(void) 26 { 27 return global_trigger_mask; 28 } 29 #endif 30 arch_local_save_flags(void)31 static inline unsigned long arch_local_save_flags(void) 32 { 33 return __core_reg_get(TXMASKI); 34 } 35 arch_irqs_disabled_flags(unsigned long flags)36 static inline int arch_irqs_disabled_flags(unsigned long flags) 37 { 38 return (flags & ~INTS_OFF_MASK) == 0; 39 } 40 arch_irqs_disabled(void)41 static inline int arch_irqs_disabled(void) 42 { 43 unsigned long flags = arch_local_save_flags(); 44 45 return arch_irqs_disabled_flags(flags); 46 } 47 __irqs_disabled(void)48 static inline unsigned long __irqs_disabled(void) 49 { 50 /* 51 * We shouldn't enable exceptions if they are not already 52 * enabled. This is required for chancalls to work correctly. 53 */ 54 return arch_local_save_flags() & INTS_OFF_MASK; 55 } 56 57 /* 58 * For spinlocks, etc: 59 */ arch_local_irq_save(void)60 static inline unsigned long arch_local_irq_save(void) 61 { 62 unsigned long flags = __irqs_disabled(); 63 64 asm volatile("SWAP %0,TXMASKI\n" : "=r" (flags) : "0" (flags) 65 : "memory"); 66 67 return flags; 68 } 69 arch_local_irq_restore(unsigned long flags)70 static inline void arch_local_irq_restore(unsigned long flags) 71 { 72 asm volatile("MOV TXMASKI,%0\n" : : "r" (flags) : "memory"); 73 } 74 arch_local_irq_disable(void)75 static inline void arch_local_irq_disable(void) 76 { 77 unsigned long flags = __irqs_disabled(); 78 79 asm volatile("MOV TXMASKI,%0\n" : : "r" (flags) : "memory"); 80 } 81 82 #ifdef CONFIG_SMP 83 /* Avoid circular include dependencies through <linux/preempt.h> */ 84 void arch_local_irq_enable(void); 85 #else arch_local_irq_enable(void)86 static inline void arch_local_irq_enable(void) 87 { 88 arch_local_irq_restore(get_trigger_mask()); 89 } 90 #endif 91 92 #endif /* (__ASSEMBLY__) */ 93 94 #endif /* !(_ASM_IRQFLAGS_H) */ 95