1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * include/linux/irqflags.h
3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * IRQ flags tracing: follow the state of the hardirq and softirq flags and
5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * provide callbacks for transitions between ON and OFF states.
6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * This file gets included from lowlevel asm headers too, to provide
8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * wrapped versions of the local_irq_*() APIs, based on the
9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * raw_local_irq_*() macros from the lowlevel headers.
10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef _LINUX_TRACE_IRQFLAGS_H
12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _LINUX_TRACE_IRQFLAGS_H
13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_TRACE_IRQFLAGS
15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru  extern void trace_hardirqs_on(void);
16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru  extern void trace_hardirqs_off(void);
17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru  extern void trace_softirqs_on(unsigned long ip);
18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru  extern void trace_softirqs_off(unsigned long ip);
19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirq_context(p)	((p)->hardirq_context)
20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirq_context(p)	((p)->softirq_context)
21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirqs_enabled(p)	((p)->hardirqs_enabled)
22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirqs_enabled(p)	((p)->softirqs_enabled)
23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirq_enter()	do { current->hardirq_context++; } while (0)
24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirq_exit()	do { current->hardirq_context--; } while (0)
25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirq_enter()	do { current->softirq_context++; } while (0)
26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirq_exit()	do { current->softirq_context--; } while (0)
27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define INIT_TRACE_IRQFLAGS	.softirqs_enabled = 1,
28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirqs_on()		do { } while (0)
30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirqs_off()		do { } while (0)
31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirqs_on(ip)		do { } while (0)
32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirqs_off(ip)		do { } while (0)
33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirq_context(p)	0
34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirq_context(p)	0
35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirqs_enabled(p)	0
36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirqs_enabled(p)	0
37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirq_enter()		do { } while (0)
38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_hardirq_exit()		do { } while (0)
39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirq_enter()		do { } while (0)
40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define trace_softirq_exit()		do { } while (0)
41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define INIT_TRACE_IRQFLAGS
42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/irqflags.h>
47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_enable() \
49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0)
50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_disable() \
51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)
52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_save(flags) \
53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	do { raw_local_irq_save(flags); trace_hardirqs_off(); } while (0)
54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_restore(flags)				\
56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	do {							\
57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		if (raw_irqs_disabled_flags(flags)) {		\
58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			raw_local_irq_restore(flags);		\
59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			trace_hardirqs_off();			\
60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		} else {					\
61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			trace_hardirqs_on();			\
62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			raw_local_irq_restore(flags);		\
63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		}						\
64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	} while (0)
65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else /* !CONFIG_TRACE_IRQFLAGS_SUPPORT */
66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The local_irq_*() APIs are equal to the raw_local_irq*()
68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * if !TRACE_IRQFLAGS.
69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define raw_local_irq_disable()	local_irq_disable()
71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define raw_local_irq_enable()		local_irq_enable()
72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define raw_local_irq_save(flags)	local_irq_save(flags)
73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define raw_local_irq_restore(flags)	local_irq_restore(flags)
74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */
75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define safe_halt()						\
78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	do {							\
79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		trace_hardirqs_on();				\
80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		raw_safe_halt();				\
81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	} while (0)
82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_save_flags(flags)		raw_local_save_flags(flags)
84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define irqs_disabled()						\
86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({								\
87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long flags;					\
88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru								\
89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	raw_local_save_flags(flags);				\
90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	raw_irqs_disabled_flags(flags);				\
91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru})
92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define irqs_disabled_flags(flags)	raw_irqs_disabled_flags(flags)
94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif		/* CONFIG_X86 */
95c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
96c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
97