Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mn10300/include/asm/irqflags.h
15126 views
1
/* MN10300 IRQ flag handling
2
*
3
* Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public Licence
8
* as published by the Free Software Foundation; either version
9
* 2 of the Licence, or (at your option) any later version.
10
*/
11
12
#ifndef _ASM_IRQFLAGS_H
13
#define _ASM_IRQFLAGS_H
14
15
#include <asm/cpu-regs.h>
16
#ifndef __ASSEMBLY__
17
#include <linux/smp.h>
18
#endif
19
20
/*
21
* interrupt control
22
* - "disabled": run in IM1/2
23
* - level 0 - kernel debugger
24
* - level 1 - virtual serial DMA (if present)
25
* - level 5 - normal interrupt priority
26
* - level 6 - timer interrupt
27
* - "enabled": run in IM7
28
*/
29
#define MN10300_CLI_LEVEL (CONFIG_LINUX_CLI_LEVEL << EPSW_IM_SHIFT)
30
31
#ifndef __ASSEMBLY__
32
33
static inline unsigned long arch_local_save_flags(void)
34
{
35
unsigned long flags;
36
37
asm volatile("mov epsw,%0" : "=d"(flags));
38
return flags;
39
}
40
41
static inline void arch_local_irq_disable(void)
42
{
43
asm volatile(
44
" and %0,epsw \n"
45
" or %1,epsw \n"
46
" nop \n"
47
" nop \n"
48
" nop \n"
49
:
50
: "i"(~EPSW_IM), "i"(EPSW_IE | MN10300_CLI_LEVEL)
51
: "memory");
52
}
53
54
static inline unsigned long arch_local_irq_save(void)
55
{
56
unsigned long flags;
57
58
flags = arch_local_save_flags();
59
arch_local_irq_disable();
60
return flags;
61
}
62
63
/*
64
* we make sure arch_irq_enable() doesn't cause priority inversion
65
*/
66
extern unsigned long __mn10300_irq_enabled_epsw[];
67
68
static inline void arch_local_irq_enable(void)
69
{
70
unsigned long tmp;
71
int cpu = raw_smp_processor_id();
72
73
asm volatile(
74
" mov epsw,%0 \n"
75
" and %1,%0 \n"
76
" or %2,%0 \n"
77
" mov %0,epsw \n"
78
: "=&d"(tmp)
79
: "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw[cpu])
80
: "memory", "cc");
81
}
82
83
static inline void arch_local_irq_restore(unsigned long flags)
84
{
85
asm volatile(
86
" mov %0,epsw \n"
87
" nop \n"
88
" nop \n"
89
" nop \n"
90
:
91
: "d"(flags)
92
: "memory", "cc");
93
}
94
95
static inline bool arch_irqs_disabled_flags(unsigned long flags)
96
{
97
return (flags & (EPSW_IE | EPSW_IM)) != (EPSW_IE | EPSW_IM_7);
98
}
99
100
static inline bool arch_irqs_disabled(void)
101
{
102
return arch_irqs_disabled_flags(arch_local_save_flags());
103
}
104
105
/*
106
* Hook to save power by halting the CPU
107
* - called from the idle loop
108
* - must reenable interrupts (which takes three instruction cycles to complete)
109
*/
110
static inline void arch_safe_halt(void)
111
{
112
#ifdef CONFIG_SMP
113
arch_local_irq_enable();
114
#else
115
asm volatile(
116
" or %0,epsw \n"
117
" nop \n"
118
" nop \n"
119
" bset %2,(%1) \n"
120
:
121
: "i"(EPSW_IE|EPSW_IM), "n"(&CPUM), "i"(CPUM_SLEEP)
122
: "cc");
123
#endif
124
}
125
126
#define __sleep_cpu() \
127
do { \
128
asm volatile( \
129
" bset %1,(%0)\n" \
130
"1: btst %1,(%0)\n" \
131
" bne 1b\n" \
132
: \
133
: "i"(&CPUM), "i"(CPUM_SLEEP) \
134
: "cc" \
135
); \
136
} while (0)
137
138
static inline void arch_local_cli(void)
139
{
140
asm volatile(
141
" and %0,epsw \n"
142
" nop \n"
143
" nop \n"
144
" nop \n"
145
:
146
: "i"(~EPSW_IE)
147
: "memory"
148
);
149
}
150
151
static inline unsigned long arch_local_cli_save(void)
152
{
153
unsigned long flags = arch_local_save_flags();
154
arch_local_cli();
155
return flags;
156
}
157
158
static inline void arch_local_sti(void)
159
{
160
asm volatile(
161
" or %0,epsw \n"
162
:
163
: "i"(EPSW_IE)
164
: "memory");
165
}
166
167
static inline void arch_local_change_intr_mask_level(unsigned long level)
168
{
169
asm volatile(
170
" and %0,epsw \n"
171
" or %1,epsw \n"
172
:
173
: "i"(~EPSW_IM), "i"(EPSW_IE | level)
174
: "cc", "memory");
175
}
176
177
#else /* !__ASSEMBLY__ */
178
179
#define LOCAL_SAVE_FLAGS(reg) \
180
mov epsw,reg
181
182
#define LOCAL_IRQ_DISABLE \
183
and ~EPSW_IM,epsw; \
184
or EPSW_IE|MN10300_CLI_LEVEL,epsw; \
185
nop; \
186
nop; \
187
nop
188
189
#define LOCAL_IRQ_ENABLE \
190
or EPSW_IE|EPSW_IM_7,epsw
191
192
#define LOCAL_IRQ_RESTORE(reg) \
193
mov reg,epsw
194
195
#define LOCAL_CLI_SAVE(reg) \
196
mov epsw,reg; \
197
and ~EPSW_IE,epsw; \
198
nop; \
199
nop; \
200
nop
201
202
#define LOCAL_CLI \
203
and ~EPSW_IE,epsw; \
204
nop; \
205
nop; \
206
nop
207
208
#define LOCAL_STI \
209
or EPSW_IE,epsw
210
211
#define LOCAL_CHANGE_INTR_MASK_LEVEL(level) \
212
and ~EPSW_IM,epsw; \
213
or EPSW_IE|(level),epsw
214
215
#endif /* __ASSEMBLY__ */
216
#endif /* _ASM_IRQFLAGS_H */
217
218