irqflags.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright IBM Corp. 2006, 2010
  4. * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
  5. */
  6. #ifndef __ASM_IRQFLAGS_H
  7. #define __ASM_IRQFLAGS_H
  8. #include <linux/types.h>
  9. #define ARCH_IRQ_ENABLED (3UL << (BITS_PER_LONG - 8))
  10. /* store then OR system mask. */
  11. #define __arch_local_irq_stosm(__or) \
  12. ({ \
  13. unsigned long __mask; \
  14. asm volatile( \
  15. " stosm %0,%1" \
  16. : "=Q" (__mask) : "i" (__or) : "memory"); \
  17. __mask; \
  18. })
  19. /* store then AND system mask. */
  20. #define __arch_local_irq_stnsm(__and) \
  21. ({ \
  22. unsigned long __mask; \
  23. asm volatile( \
  24. " stnsm %0,%1" \
  25. : "=Q" (__mask) : "i" (__and) : "memory"); \
  26. __mask; \
  27. })
  28. /* set system mask. */
  29. static __always_inline void __arch_local_irq_ssm(unsigned long flags)
  30. {
  31. asm volatile("ssm %0" : : "Q" (flags) : "memory");
  32. }
  33. #ifdef CONFIG_KMSAN
  34. #define arch_local_irq_attributes noinline notrace __no_sanitize_memory __maybe_unused
  35. #else
  36. #define arch_local_irq_attributes __always_inline
  37. #endif
  38. static arch_local_irq_attributes unsigned long arch_local_save_flags(void)
  39. {
  40. return __arch_local_irq_stnsm(0xff);
  41. }
  42. static arch_local_irq_attributes unsigned long arch_local_irq_save(void)
  43. {
  44. return __arch_local_irq_stnsm(0xfc);
  45. }
  46. static __always_inline void arch_local_irq_disable(void)
  47. {
  48. arch_local_irq_save();
  49. }
  50. static arch_local_irq_attributes void arch_local_irq_enable_external(void)
  51. {
  52. __arch_local_irq_stosm(0x01);
  53. }
  54. static arch_local_irq_attributes void arch_local_irq_enable(void)
  55. {
  56. __arch_local_irq_stosm(0x03);
  57. }
  58. /* This only restores external and I/O interrupt state */
  59. static __always_inline void arch_local_irq_restore(unsigned long flags)
  60. {
  61. /* only disabled->disabled and disabled->enabled is valid */
  62. if (flags & ARCH_IRQ_ENABLED)
  63. arch_local_irq_enable();
  64. }
  65. static __always_inline bool arch_irqs_disabled_flags(unsigned long flags)
  66. {
  67. return !(flags & ARCH_IRQ_ENABLED);
  68. }
  69. static __always_inline bool arch_irqs_disabled(void)
  70. {
  71. return arch_irqs_disabled_flags(arch_local_save_flags());
  72. }
  73. #endif /* __ASM_IRQFLAGS_H */