irqflags.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Xtensa IRQ flags handling functions
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License. See the file "COPYING" in the main directory of this archive
  6. * for more details.
  7. *
  8. * Copyright (C) 2001 - 2005 Tensilica Inc.
  9. * Copyright (C) 2015 Cadence Design Systems Inc.
  10. */
  11. #ifndef _XTENSA_IRQFLAGS_H
  12. #define _XTENSA_IRQFLAGS_H
  13. #include <linux/stringify.h>
  14. #include <linux/types.h>
  15. #include <asm/processor.h>
  16. static inline unsigned long arch_local_save_flags(void)
  17. {
  18. unsigned long flags;
  19. asm volatile("rsr %0, ps" : "=a" (flags));
  20. return flags;
  21. }
  22. static inline unsigned long arch_local_irq_save(void)
  23. {
  24. unsigned long flags;
  25. #if XTENSA_FAKE_NMI
  26. #if defined(CONFIG_DEBUG_MISC) && (LOCKLEVEL | TOPLEVEL) >= XCHAL_DEBUGLEVEL
  27. unsigned long tmp;
  28. asm volatile("rsr %0, ps\t\n"
  29. "extui %1, %0, 0, 4\t\n"
  30. "bgei %1, "__stringify(LOCKLEVEL)", 1f\t\n"
  31. "rsil %0, "__stringify(LOCKLEVEL)"\n"
  32. "1:"
  33. : "=a" (flags), "=a" (tmp) :: "memory");
  34. #else
  35. asm volatile("rsr %0, ps\t\n"
  36. "or %0, %0, %1\t\n"
  37. "xsr %0, ps\t\n"
  38. "rsync"
  39. : "=&a" (flags) : "a" (LOCKLEVEL) : "memory");
  40. #endif
  41. #else
  42. asm volatile("rsil %0, "__stringify(LOCKLEVEL)
  43. : "=a" (flags) :: "memory");
  44. #endif
  45. return flags;
  46. }
  47. static inline void arch_local_irq_disable(void)
  48. {
  49. arch_local_irq_save();
  50. }
  51. static inline void arch_local_irq_enable(void)
  52. {
  53. unsigned long flags;
  54. asm volatile("rsil %0, 0" : "=a" (flags) :: "memory");
  55. }
  56. static inline void arch_local_irq_restore(unsigned long flags)
  57. {
  58. asm volatile("wsr %0, ps; rsync"
  59. :: "a" (flags) : "memory");
  60. }
  61. static inline bool arch_irqs_disabled_flags(unsigned long flags)
  62. {
  63. #if XCHAL_EXCM_LEVEL < LOCKLEVEL || (1 << PS_EXCM_BIT) < LOCKLEVEL
  64. #error "XCHAL_EXCM_LEVEL and 1<<PS_EXCM_BIT must be no less than LOCKLEVEL"
  65. #endif
  66. return (flags & (PS_INTLEVEL_MASK | (1 << PS_EXCM_BIT))) >= LOCKLEVEL;
  67. }
  68. static inline bool arch_irqs_disabled(void)
  69. {
  70. return arch_irqs_disabled_flags(arch_local_save_flags());
  71. }
  72. #endif /* _XTENSA_IRQFLAGS_H */