hw_irq.h 5.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3
/*
 * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
 */
K
Kumar Gala 已提交
4 5 6
#ifndef _ASM_POWERPC_HW_IRQ_H
#define _ASM_POWERPC_HW_IRQ_H

L
Linus Torvalds 已提交
7 8 9
#ifdef __KERNEL__

#include <linux/errno.h>
10
#include <linux/compiler.h>
K
Kumar Gala 已提交
11 12
#include <asm/ptrace.h>
#include <asm/processor.h>
L
Linus Torvalds 已提交
13

14 15 16 17 18 19 20 21 22 23 24 25 26 27
#ifdef CONFIG_PPC64

/*
 * PACA flags in paca->irq_happened.
 *
 * This bits are set when interrupts occur while soft-disabled
 * and allow a proper replay. Additionally, PACA_IRQ_HARD_DIS
 * is set whenever we manually hard disable.
 */
#define PACA_IRQ_HARD_DIS	0x01
#define PACA_IRQ_DBELL		0x02
#define PACA_IRQ_EE		0x04
#define PACA_IRQ_DEC		0x08 /* Or FIT */
#define PACA_IRQ_EE_EDGE	0x10 /* BookE only */
28
#define PACA_IRQ_HMI		0x20
29 30 31 32 33

#endif /* CONFIG_PPC64 */

#ifndef __ASSEMBLY__

34
extern void replay_system_reset(void);
35 36
extern void __replay_interrupt(unsigned int vector);

37
extern void timer_interrupt(struct pt_regs *);
38
extern void performance_monitor_exception(struct pt_regs *regs);
39 40
extern void WatchdogException(struct pt_regs *regs);
extern void unknown_exception(struct pt_regs *regs);
L
Linus Torvalds 已提交
41

42 43 44
#ifdef CONFIG_PPC64
#include <asm/paca.h>

D
David Howells 已提交
45
static inline unsigned long arch_local_save_flags(void)
46
{
47 48
	unsigned long flags;

D
David Howells 已提交
49 50 51 52
	asm volatile(
		"lbz %0,%1(13)"
		: "=r" (flags)
		: "i" (offsetof(struct paca_struct, soft_enabled)));
53 54

	return flags;
55 56
}

D
David Howells 已提交
57
static inline unsigned long arch_local_irq_disable(void)
58
{
59 60
	unsigned long flags, zero;

D
David Howells 已提交
61 62 63 64 65
	asm volatile(
		"li %1,0; lbz %0,%2(13); stb %1,%2(13)"
		: "=r" (flags), "=&r" (zero)
		: "i" (offsetof(struct paca_struct, soft_enabled))
		: "memory");
66 67

	return flags;
68
}
L
Linus Torvalds 已提交
69

D
David Howells 已提交
70
extern void arch_local_irq_restore(unsigned long);
L
Linus Torvalds 已提交
71

D
David Howells 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85
static inline void arch_local_irq_enable(void)
{
	arch_local_irq_restore(1);
}

static inline unsigned long arch_local_irq_save(void)
{
	return arch_local_irq_disable();
}

static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
	return flags == 0;
}
L
Linus Torvalds 已提交
86

D
David Howells 已提交
87 88 89 90
static inline bool arch_irqs_disabled(void)
{
	return arch_irqs_disabled_flags(arch_local_save_flags());
}
L
Linus Torvalds 已提交
91

92
#ifdef CONFIG_PPC_BOOK3E
93 94
#define __hard_irq_enable()	asm volatile("wrteei 1" : : : "memory")
#define __hard_irq_disable()	asm volatile("wrteei 0" : : : "memory")
95
#else
96 97
#define __hard_irq_enable()	__mtmsrd(local_paca->kernel_msr | MSR_EE, 1)
#define __hard_irq_disable()	__mtmsrd(local_paca->kernel_msr, 1)
98
#endif
99

100
#define hard_irq_disable()	do {			\
101
	u8 _was_enabled;				\
102
	__hard_irq_disable();				\
103 104 105
	_was_enabled = local_paca->soft_enabled;	\
	local_paca->soft_enabled = 0;			\
	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;	\
106 107
	if (_was_enabled)				\
		trace_hardirqs_off();			\
108
} while(0)
109

110 111 112 113 114
static inline bool lazy_irq_pending(void)
{
	return !!(get_paca()->irq_happened & ~PACA_IRQ_HARD_DIS);
}

115 116 117 118 119 120 121 122 123 124 125
/*
 * This is called by asynchronous interrupts to conditionally
 * re-enable hard interrupts when soft-disabled after having
 * cleared the source of the interrupt
 */
static inline void may_hard_irq_enable(void)
{
	get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
	if (!(get_paca()->irq_happened & PACA_IRQ_EE))
		__hard_irq_enable();
}
126

127 128 129 130 131
static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
{
	return !regs->softe;
}

132
extern bool prep_irq_for_idle(void);
133
extern bool prep_irq_for_idle_irqsoff(void);
134
extern void irq_set_pending_from_srr1(unsigned long srr1);
135 136

#define fini_irq_for_idle_irqsoff() trace_hardirqs_off();
137

138 139
extern void force_external_irq_replay(void);

D
David Howells 已提交
140
#else /* CONFIG_PPC64 */
L
Linus Torvalds 已提交
141

K
Kumar Gala 已提交
142
#define SET_MSR_EE(x)	mtmsr(x)
D
David Howells 已提交
143 144 145 146 147 148 149 150 151 152

static inline unsigned long arch_local_save_flags(void)
{
	return mfmsr();
}

static inline void arch_local_irq_restore(unsigned long flags)
{
#if defined(CONFIG_BOOKE)
	asm volatile("wrtee %0" : : "r" (flags) : "memory");
K
Kumar Gala 已提交
153
#else
D
David Howells 已提交
154
	mtmsr(flags);
K
Kumar Gala 已提交
155
#endif
D
David Howells 已提交
156
}
L
Linus Torvalds 已提交
157

D
David Howells 已提交
158
static inline unsigned long arch_local_irq_save(void)
L
Linus Torvalds 已提交
159
{
D
David Howells 已提交
160
	unsigned long flags = arch_local_save_flags();
K
Kumar Gala 已提交
161
#ifdef CONFIG_BOOKE
D
David Howells 已提交
162
	asm volatile("wrteei 0" : : : "memory");
163 164
#elif defined(CONFIG_PPC_8xx)
	wrtspr(SPRN_EID);
K
Kumar Gala 已提交
165
#else
D
David Howells 已提交
166
	SET_MSR_EE(flags & ~MSR_EE);
K
Kumar Gala 已提交
167
#endif
D
David Howells 已提交
168
	return flags;
L
Linus Torvalds 已提交
169 170
}

D
David Howells 已提交
171
static inline void arch_local_irq_disable(void)
L
Linus Torvalds 已提交
172
{
K
Kumar Gala 已提交
173
#ifdef CONFIG_BOOKE
D
David Howells 已提交
174
	asm volatile("wrteei 0" : : : "memory");
175 176
#elif defined(CONFIG_PPC_8xx)
	wrtspr(SPRN_EID);
K
Kumar Gala 已提交
177
#else
D
David Howells 已提交
178
	arch_local_irq_save();
K
Kumar Gala 已提交
179
#endif
L
Linus Torvalds 已提交
180 181
}

D
David Howells 已提交
182
static inline void arch_local_irq_enable(void)
L
Linus Torvalds 已提交
183
{
K
Kumar Gala 已提交
184
#ifdef CONFIG_BOOKE
D
David Howells 已提交
185
	asm volatile("wrteei 1" : : : "memory");
186 187
#elif defined(CONFIG_PPC_8xx)
	wrtspr(SPRN_EIE);
K
Kumar Gala 已提交
188
#else
D
David Howells 已提交
189 190
	unsigned long msr = mfmsr();
	SET_MSR_EE(msr | MSR_EE);
K
Kumar Gala 已提交
191
#endif
L
Linus Torvalds 已提交
192 193
}

D
David Howells 已提交
194
static inline bool arch_irqs_disabled_flags(unsigned long flags)
195 196 197 198
{
	return (flags & MSR_EE) == 0;
}

D
David Howells 已提交
199 200 201 202 203 204 205
static inline bool arch_irqs_disabled(void)
{
	return arch_irqs_disabled_flags(arch_local_save_flags());
}

#define hard_irq_disable()		arch_local_irq_disable()

206 207 208 209 210
static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
{
	return !(regs->msr & MSR_EE);
}

211 212
static inline void may_hard_irq_enable(void) { }

213
#endif /* CONFIG_PPC64 */
L
Linus Torvalds 已提交
214

215 216
#define ARCH_IRQ_INIT_FLAGS	IRQ_NOREQUEST

217 218 219
/*
 * interrupt-retrigger: should we handle this via lost interrupts and IPIs
 * or should we not care like we do now ? --BenH.
L
Linus Torvalds 已提交
220
 */
221
struct irq_chip;
K
Kumar Gala 已提交
222

223
#endif  /* __ASSEMBLY__ */
K
Kumar Gala 已提交
224 225
#endif	/* __KERNEL__ */
#endif	/* _ASM_POWERPC_HW_IRQ_H */