| /* SPDX-License-Identifier: GPL-2.0 */ |
| /* |
| * IRQ flags defines. |
| * |
| * Copyright (C) 1998-2003 Hewlett-Packard Co |
| * David Mosberger-Tang <davidm@hpl.hp.com> |
| * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com> |
| * Copyright (C) 1999 Don Dugger <don.dugger@intel.com> |
| */ |
| |
| #ifndef _ASM_IA64_IRQFLAGS_H |
| #define _ASM_IA64_IRQFLAGS_H |
| |
| #include <asm/pal.h> |
| #include <asm/kregs.h> |
| |
| #ifdef CONFIG_IA64_DEBUG_IRQ |
| extern unsigned long last_cli_ip; |
| static inline void arch_maybe_save_ip(unsigned long flags) |
| { |
| if (flags & IA64_PSR_I) |
| last_cli_ip = ia64_getreg(_IA64_REG_IP); |
| } |
| #else |
| #define arch_maybe_save_ip(flags) do {} while (0) |
| #endif |
| |
| /* |
| * - clearing psr.i is implicitly serialized (visible by next insn) |
| * - setting psr.i requires data serialization |
| * - we need a stop-bit before reading PSR because we sometimes |
| * write a floating-point register right before reading the PSR |
| * and that writes to PSR.mfl |
| */ |
| |
| static inline unsigned long arch_local_save_flags(void) |
| { |
| ia64_stop(); |
| #ifdef CONFIG_PARAVIRT |
| return ia64_get_psr_i(); |
| #else |
| return ia64_getreg(_IA64_REG_PSR); |
| #endif |
| } |
| |
| static inline unsigned long arch_local_irq_save(void) |
| { |
| unsigned long flags = arch_local_save_flags(); |
| |
| ia64_stop(); |
| ia64_rsm(IA64_PSR_I); |
| arch_maybe_save_ip(flags); |
| return flags; |
| } |
| |
| static inline void arch_local_irq_disable(void) |
| { |
| #ifdef CONFIG_IA64_DEBUG_IRQ |
| arch_local_irq_save(); |
| #else |
| ia64_stop(); |
| ia64_rsm(IA64_PSR_I); |
| #endif |
| } |
| |
| static inline void arch_local_irq_enable(void) |
| { |
| ia64_stop(); |
| ia64_ssm(IA64_PSR_I); |
| ia64_srlz_d(); |
| } |
| |
| static inline void arch_local_irq_restore(unsigned long flags) |
| { |
| #ifdef CONFIG_IA64_DEBUG_IRQ |
| unsigned long old_psr = arch_local_save_flags(); |
| #endif |
| ia64_intrin_local_irq_restore(flags & IA64_PSR_I); |
| arch_maybe_save_ip(old_psr & ~flags); |
| } |
| |
| static inline bool arch_irqs_disabled_flags(unsigned long flags) |
| { |
| return (flags & IA64_PSR_I) == 0; |
| } |
| |
| static inline bool arch_irqs_disabled(void) |
| { |
| return arch_irqs_disabled_flags(arch_local_save_flags()); |
| } |
| |
| static inline void arch_safe_halt(void) |
| { |
| arch_local_irq_enable(); |
| ia64_pal_halt_light(); /* PAL_HALT_LIGHT */ |
| } |
| |
| |
| #endif /* _ASM_IA64_IRQFLAGS_H */ |