1/*
2 * IRQ flags handling
3 *
4 * This file gets included from lowlevel asm headers too, to provide
5 * wrapped versions of the local_irq_*() APIs, based on the
6 * raw_local_irq_*() functions from the lowlevel headers.
7 */
8#ifndef _ASM_IRQFLAGS_H
9#define _ASM_IRQFLAGS_H
10
11#ifndef __ASSEMBLY__
12
13#include <asm/core_reg.h>
14#include <asm/metag_regs.h>
15
16#define INTS_OFF_MASK TXSTATI_BGNDHALT_BIT
17
18#ifdef CONFIG_SMP
19extern unsigned int get_trigger_mask(void);
20#else
21
22extern unsigned int global_trigger_mask;
23
24static inline unsigned int get_trigger_mask(void)
25{
26	return global_trigger_mask;
27}
28#endif
29
30static inline unsigned long arch_local_save_flags(void)
31{
32	return __core_reg_get(TXMASKI);
33}
34
35static inline int arch_irqs_disabled_flags(unsigned long flags)
36{
37	return (flags & ~INTS_OFF_MASK) == 0;
38}
39
40static inline int arch_irqs_disabled(void)
41{
42	unsigned long flags = arch_local_save_flags();
43
44	return arch_irqs_disabled_flags(flags);
45}
46
47static inline unsigned long __irqs_disabled(void)
48{
49	/*
50	 * We shouldn't enable exceptions if they are not already
51	 * enabled. This is required for chancalls to work correctly.
52	 */
53	return arch_local_save_flags() & INTS_OFF_MASK;
54}
55
56/*
57 * For spinlocks, etc:
58 */
59static inline unsigned long arch_local_irq_save(void)
60{
61	unsigned long flags = __irqs_disabled();
62
63	asm volatile("SWAP %0,TXMASKI\n" : "=r" (flags) : "0" (flags)
64		     : "memory");
65
66	return flags;
67}
68
69static inline void arch_local_irq_restore(unsigned long flags)
70{
71	asm volatile("MOV TXMASKI,%0\n" : : "r" (flags) : "memory");
72}
73
74static inline void arch_local_irq_disable(void)
75{
76	unsigned long flags = __irqs_disabled();
77
78	asm volatile("MOV TXMASKI,%0\n" : : "r" (flags) : "memory");
79}
80
81#ifdef CONFIG_SMP
82/* Avoid circular include dependencies through <linux/preempt.h> */
83void arch_local_irq_enable(void);
84#else
85static inline void arch_local_irq_enable(void)
86{
87	arch_local_irq_restore(get_trigger_mask());
88}
89#endif
90
91#endif /* (__ASSEMBLY__) */
92
93#endif /* !(_ASM_IRQFLAGS_H) */
94