1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2c6557e7fSMartin Schwidefsky /* 3428aecf6SHeiko Carstens * Copyright IBM Corp. 2006, 2010 4428aecf6SHeiko Carstens * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> 5c6557e7fSMartin Schwidefsky */ 6c6557e7fSMartin Schwidefsky 7c6557e7fSMartin Schwidefsky #ifndef __ASM_IRQFLAGS_H 8c6557e7fSMartin Schwidefsky #define __ASM_IRQFLAGS_H 9c6557e7fSMartin Schwidefsky 10428aecf6SHeiko Carstens #include <linux/types.h> 11c6557e7fSMartin Schwidefsky 12204ee2c5SChristian Borntraeger #define ARCH_IRQ_ENABLED (3UL << (BITS_PER_LONG - 8)) 13204ee2c5SChristian Borntraeger 14df9ee292SDavid Howells /* store then OR system mask. */ 15df9ee292SDavid Howells #define __arch_local_irq_stosm(__or) \ 16c6557e7fSMartin Schwidefsky ({ \ 17c6557e7fSMartin Schwidefsky unsigned long __mask; \ 18c6557e7fSMartin Schwidefsky asm volatile( \ 19c6557e7fSMartin Schwidefsky " stosm %0,%1" \ 20c6557e7fSMartin Schwidefsky : "=Q" (__mask) : "i" (__or) : "memory"); \ 21c6557e7fSMartin Schwidefsky __mask; \ 22c6557e7fSMartin Schwidefsky }) 23c6557e7fSMartin Schwidefsky 24df9ee292SDavid Howells /* store then AND system mask. */ 25df9ee292SDavid Howells #define __arch_local_irq_stnsm(__and) \ 26c6557e7fSMartin Schwidefsky ({ \ 27c6557e7fSMartin Schwidefsky unsigned long __mask; \ 28c6557e7fSMartin Schwidefsky asm volatile( \ 29c6557e7fSMartin Schwidefsky " stnsm %0,%1" \ 30c6557e7fSMartin Schwidefsky : "=Q" (__mask) : "i" (__and) : "memory"); \ 31c6557e7fSMartin Schwidefsky __mask; \ 32c6557e7fSMartin Schwidefsky }) 33c6557e7fSMartin Schwidefsky 34c6557e7fSMartin Schwidefsky /* set system mask. */ __arch_local_irq_ssm(unsigned long flags)354aca3ab4SHeiko Carstensstatic __always_inline void __arch_local_irq_ssm(unsigned long flags) 36c6557e7fSMartin Schwidefsky { 37df9ee292SDavid Howells asm volatile("ssm %0" : : "Q" (flags) : "memory"); 38c6557e7fSMartin Schwidefsky } 39c6557e7fSMartin Schwidefsky 40*1b301f5fSIlya Leoshkevich #ifdef CONFIG_KMSAN 41*1b301f5fSIlya Leoshkevich #define arch_local_irq_attributes noinline notrace __no_sanitize_memory __maybe_unused 42*1b301f5fSIlya Leoshkevich #else 43*1b301f5fSIlya Leoshkevich #define arch_local_irq_attributes __always_inline 44*1b301f5fSIlya Leoshkevich #endif 45*1b301f5fSIlya Leoshkevich arch_local_save_flags(void)46*1b301f5fSIlya Leoshkevichstatic arch_local_irq_attributes unsigned long arch_local_save_flags(void) 47c6557e7fSMartin Schwidefsky { 4881fc77fbSChristian Borntraeger return __arch_local_irq_stnsm(0xff); 49c6557e7fSMartin Schwidefsky } 50c6557e7fSMartin Schwidefsky arch_local_irq_save(void)51*1b301f5fSIlya Leoshkevichstatic arch_local_irq_attributes unsigned long arch_local_irq_save(void) 52c6557e7fSMartin Schwidefsky { 53df9ee292SDavid Howells return __arch_local_irq_stnsm(0xfc); 54c6557e7fSMartin Schwidefsky } 55c6557e7fSMartin Schwidefsky arch_local_irq_disable(void)564aca3ab4SHeiko Carstensstatic __always_inline void arch_local_irq_disable(void) 57df9ee292SDavid Howells { 58df9ee292SDavid Howells arch_local_irq_save(); 59df9ee292SDavid Howells } 60df9ee292SDavid Howells arch_local_irq_enable_external(void)61*1b301f5fSIlya Leoshkevichstatic arch_local_irq_attributes void arch_local_irq_enable_external(void) 62*1b301f5fSIlya Leoshkevich { 63*1b301f5fSIlya Leoshkevich __arch_local_irq_stosm(0x01); 64*1b301f5fSIlya Leoshkevich } 65*1b301f5fSIlya Leoshkevich arch_local_irq_enable(void)66*1b301f5fSIlya Leoshkevichstatic arch_local_irq_attributes void arch_local_irq_enable(void) 67df9ee292SDavid Howells { 68df9ee292SDavid Howells __arch_local_irq_stosm(0x03); 69df9ee292SDavid Howells } 70df9ee292SDavid Howells 71204ee2c5SChristian Borntraeger /* This only restores external and I/O interrupt state */ arch_local_irq_restore(unsigned long flags)724aca3ab4SHeiko Carstensstatic __always_inline void arch_local_irq_restore(unsigned long flags) 73df9ee292SDavid Howells { 74204ee2c5SChristian Borntraeger /* only disabled->disabled and disabled->enabled is valid */ 75204ee2c5SChristian Borntraeger if (flags & ARCH_IRQ_ENABLED) 76204ee2c5SChristian Borntraeger arch_local_irq_enable(); 77df9ee292SDavid Howells } 78df9ee292SDavid Howells arch_irqs_disabled_flags(unsigned long flags)794aca3ab4SHeiko Carstensstatic __always_inline bool arch_irqs_disabled_flags(unsigned long flags) 80c6557e7fSMartin Schwidefsky { 81204ee2c5SChristian Borntraeger return !(flags & ARCH_IRQ_ENABLED); 82c6557e7fSMartin Schwidefsky } 83c6557e7fSMartin Schwidefsky arch_irqs_disabled(void)844aca3ab4SHeiko Carstensstatic __always_inline bool arch_irqs_disabled(void) 85df9ee292SDavid Howells { 86df9ee292SDavid Howells return arch_irqs_disabled_flags(arch_local_save_flags()); 87df9ee292SDavid Howells } 88c6557e7fSMartin Schwidefsky 89c6557e7fSMartin Schwidefsky #endif /* __ASM_IRQFLAGS_H */ 90