irqflags.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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/types.h>
  14. #include <asm/processor.h>
  15. static inline unsigned long arch_local_save_flags(void)
  16. {
  17. unsigned long flags;
  18. asm volatile("rsr %0, ps" : "=a" (flags));
  19. return flags;
  20. }
  21. static inline unsigned long arch_local_irq_save(void)
  22. {
  23. unsigned long flags;
  24. #if XTENSA_FAKE_NMI
  25. #if defined(CONFIG_DEBUG_KERNEL) && (LOCKLEVEL | TOPLEVEL) >= XCHAL_DEBUGLEVEL
  26. unsigned long tmp;
  27. asm volatile("rsr %0, ps\t\n"
  28. "extui %1, %0, 0, 4\t\n"
  29. "bgei %1, "__stringify(LOCKLEVEL)", 1f\t\n"
  30. "rsil %0, "__stringify(LOCKLEVEL)"\n"
  31. "1:"
  32. : "=a" (flags), "=a" (tmp) :: "memory");
  33. #else
  34. asm volatile("rsr %0, ps\t\n"
  35. "or %0, %0, %1\t\n"
  36. "xsr %0, ps\t\n"
  37. "rsync"
  38. : "=&a" (flags) : "a" (LOCKLEVEL) : "memory");
  39. #endif
  40. #else
  41. asm volatile("rsil %0, "__stringify(LOCKLEVEL)
  42. : "=a" (flags) :: "memory");
  43. #endif
  44. return flags;
  45. }
  46. static inline void arch_local_irq_disable(void)
  47. {
  48. arch_local_irq_save();
  49. }
  50. static inline void arch_local_irq_enable(void)
  51. {
  52. unsigned long flags;
  53. asm volatile("rsil %0, 0" : "=a" (flags) :: "memory");
  54. }
  55. static inline void arch_local_irq_restore(unsigned long flags)
  56. {
  57. asm volatile("wsr %0, ps; rsync"
  58. :: "a" (flags) : "memory");
  59. }
  60. static inline bool arch_irqs_disabled_flags(unsigned long flags)
  61. {
  62. #if XCHAL_EXCM_LEVEL < LOCKLEVEL || (1 << PS_EXCM_BIT) < LOCKLEVEL
  63. #error "XCHAL_EXCM_LEVEL and 1<<PS_EXCM_BIT must be no less than LOCKLEVEL"
  64. #endif
  65. return (flags & (PS_INTLEVEL_MASK | (1 << PS_EXCM_BIT))) >= LOCKLEVEL;
  66. }
  67. static inline bool arch_irqs_disabled(void)
  68. {
  69. return arch_irqs_disabled_flags(arch_local_save_flags());
  70. }
  71. #endif /* _XTENSA_IRQFLAGS_H */