aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-04-17 00:35:01 -0400
committerPaul Mackerras <paulus@samba.org>2008-04-18 01:38:47 -0400
commit945feb174b14e7098cc7ecf0cf4768d35bc52f9c (patch)
tree9810b2ff0efe8edbfb1506f65834ea0d553e2848 /include/asm-powerpc
parentfd3e0bbc6052ca9747a5332b382584ece83aab6d (diff)
[POWERPC] irqtrace support for 64-bit powerpc
This adds the low level irq tracing hooks to the powerpc architecture needed to enable full lockdep functionality. This is partly based on Johannes Berg's initial version. I removed the asm trampoline that isn't needed (thus improving performance) and modified all sorts of bits and pieces, reworking most of the assembly, etc... Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r--include/asm-powerpc/exception.h6
-rw-r--r--include/asm-powerpc/hw_irq.h13
-rw-r--r--include/asm-powerpc/irqflags.h37
-rw-r--r--include/asm-powerpc/rwsem.h35
-rw-r--r--include/asm-powerpc/spinlock.h1
5 files changed, 62 insertions, 30 deletions
diff --git a/include/asm-powerpc/exception.h b/include/asm-powerpc/exception.h
index 39abdb02fdef..329148b5acc6 100644
--- a/include/asm-powerpc/exception.h
+++ b/include/asm-powerpc/exception.h
@@ -228,18 +228,18 @@ label##_pSeries: \
228BEGIN_FW_FTR_SECTION; \ 228BEGIN_FW_FTR_SECTION; \
229 stb r11,PACAHARDIRQEN(r13); \ 229 stb r11,PACAHARDIRQEN(r13); \
230END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \ 230END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
231 TRACE_DISABLE_INTS; \
231BEGIN_FW_FTR_SECTION; \ 232BEGIN_FW_FTR_SECTION; \
232 mfmsr r10; \ 233 mfmsr r10; \
233 ori r10,r10,MSR_EE; \ 234 ori r10,r10,MSR_EE; \
234 mtmsrd r10,1; \ 235 mtmsrd r10,1; \
235END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 236END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
236
237#else 237#else
238#define DISABLE_INTS \ 238#define DISABLE_INTS \
239 li r11,0; \ 239 li r11,0; \
240 stb r11,PACASOFTIRQEN(r13); \ 240 stb r11,PACASOFTIRQEN(r13); \
241 stb r11,PACAHARDIRQEN(r13) 241 stb r11,PACAHARDIRQEN(r13); \
242 242 TRACE_DISABLE_INTS
243#endif /* CONFIG_PPC_ISERIES */ 243#endif /* CONFIG_PPC_ISERIES */
244 244
245#define ENABLE_INTS \ 245#define ENABLE_INTS \
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h
index a7b60bf639e0..ad8c9f7fd0e3 100644
--- a/include/asm-powerpc/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -27,7 +27,7 @@ static inline unsigned long local_get_flags(void)
27 return flags; 27 return flags;
28} 28}
29 29
30static inline unsigned long local_irq_disable(void) 30static inline unsigned long raw_local_irq_disable(void)
31{ 31{
32 unsigned long flags, zero; 32 unsigned long flags, zero;
33 33
@@ -39,14 +39,15 @@ static inline unsigned long local_irq_disable(void)
39 return flags; 39 return flags;
40} 40}
41 41
42extern void local_irq_restore(unsigned long); 42extern void raw_local_irq_restore(unsigned long);
43extern void iseries_handle_interrupts(void); 43extern void iseries_handle_interrupts(void);
44 44
45#define local_irq_enable() local_irq_restore(1) 45#define raw_local_irq_enable() raw_local_irq_restore(1)
46#define local_save_flags(flags) ((flags) = local_get_flags()) 46#define raw_local_save_flags(flags) ((flags) = local_get_flags())
47#define local_irq_save(flags) ((flags) = local_irq_disable()) 47#define raw_local_irq_save(flags) ((flags) = raw_local_irq_disable())
48 48
49#define irqs_disabled() (local_get_flags() == 0) 49#define raw_irqs_disabled() (local_get_flags() == 0)
50#define raw_irqs_disabled_flags(flags) ((flags) == 0)
50 51
51#define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1) 52#define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
52#define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1) 53#define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
diff --git a/include/asm-powerpc/irqflags.h b/include/asm-powerpc/irqflags.h
index 7970cbaeaa54..cc6fdba33660 100644
--- a/include/asm-powerpc/irqflags.h
+++ b/include/asm-powerpc/irqflags.h
@@ -2,30 +2,43 @@
2 * include/asm-powerpc/irqflags.h 2 * include/asm-powerpc/irqflags.h
3 * 3 *
4 * IRQ flags handling 4 * IRQ flags handling
5 *
6 * This file gets included from lowlevel asm headers too, to provide
7 * wrapped versions of the local_irq_*() APIs, based on the
8 * raw_local_irq_*() macros from the lowlevel headers.
9 */ 5 */
10#ifndef _ASM_IRQFLAGS_H 6#ifndef _ASM_IRQFLAGS_H
11#define _ASM_IRQFLAGS_H 7#define _ASM_IRQFLAGS_H
12 8
9#ifndef __ASSEMBLY__
13/* 10/*
14 * Get definitions for raw_local_save_flags(x), etc. 11 * Get definitions for raw_local_save_flags(x), etc.
15 */ 12 */
16#include <asm-powerpc/hw_irq.h> 13#include <asm-powerpc/hw_irq.h>
17 14
15#else
16#ifdef CONFIG_TRACE_IRQFLAGS
18/* 17/*
19 * Do the CPU's IRQ-state tracing from assembly code. We call a 18 * Most of the CPU's IRQ-state tracing is done from assembly code; we
20 * C function, so save all the C-clobbered registers: 19 * have to call a C function so call a wrapper that saves all the
20 * C-clobbered registers.
21 */ 21 */
22#ifdef CONFIG_TRACE_IRQFLAGS 22#define TRACE_ENABLE_INTS bl .trace_hardirqs_on
23 23#define TRACE_DISABLE_INTS bl .trace_hardirqs_off
24#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS 24#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip) \
25 25 cmpdi en, 0; \
26 bne 95f; \
27 stb en,PACASOFTIRQEN(r13); \
28 bl .trace_hardirqs_off; \
29 b skip; \
3095: bl .trace_hardirqs_on; \
31 li en,1;
32#define TRACE_AND_RESTORE_IRQ(en) \
33 TRACE_AND_RESTORE_IRQ_PARTIAL(en,96f); \
3496: stb en,PACASOFTIRQEN(r13)
26#else 35#else
27# define TRACE_IRQS_ON 36#define TRACE_ENABLE_INTS
28# define TRACE_IRQS_OFF 37#define TRACE_DISABLE_INTS
38#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip)
39#define TRACE_AND_RESTORE_IRQ(en) \
40 stb en,PACASOFTIRQEN(r13)
41#endif
29#endif 42#endif
30 43
31#endif 44#endif
diff --git a/include/asm-powerpc/rwsem.h b/include/asm-powerpc/rwsem.h
index cefc14728cc5..a6cc93b78b98 100644
--- a/include/asm-powerpc/rwsem.h
+++ b/include/asm-powerpc/rwsem.h
@@ -32,11 +32,20 @@ struct rw_semaphore {
32#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) 32#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
33 spinlock_t wait_lock; 33 spinlock_t wait_lock;
34 struct list_head wait_list; 34 struct list_head wait_list;
35#ifdef CONFIG_DEBUG_LOCK_ALLOC
36 struct lockdep_map dep_map;
37#endif
35}; 38};
36 39
40#ifdef CONFIG_DEBUG_LOCK_ALLOC
41# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
42#else
43# define __RWSEM_DEP_MAP_INIT(lockname)
44#endif
45
37#define __RWSEM_INITIALIZER(name) \ 46#define __RWSEM_INITIALIZER(name) \
38 { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \ 47 { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
39 LIST_HEAD_INIT((name).wait_list) } 48 LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) }
40 49
41#define DECLARE_RWSEM(name) \ 50#define DECLARE_RWSEM(name) \
42 struct rw_semaphore name = __RWSEM_INITIALIZER(name) 51 struct rw_semaphore name = __RWSEM_INITIALIZER(name)
@@ -46,12 +55,15 @@ extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
46extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); 55extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
47extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); 56extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
48 57
49static inline void init_rwsem(struct rw_semaphore *sem) 58extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
50{ 59 struct lock_class_key *key);
51 sem->count = RWSEM_UNLOCKED_VALUE; 60
52 spin_lock_init(&sem->wait_lock); 61#define init_rwsem(sem) \
53 INIT_LIST_HEAD(&sem->wait_list); 62 do { \
54} 63 static struct lock_class_key __key; \
64 \
65 __init_rwsem((sem), #sem, &__key); \
66 } while (0)
55 67
56/* 68/*
57 * lock for reading 69 * lock for reading
@@ -78,7 +90,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
78/* 90/*
79 * lock for writing 91 * lock for writing
80 */ 92 */
81static inline void __down_write(struct rw_semaphore *sem) 93static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
82{ 94{
83 int tmp; 95 int tmp;
84 96
@@ -88,6 +100,11 @@ static inline void __down_write(struct rw_semaphore *sem)
88 rwsem_down_write_failed(sem); 100 rwsem_down_write_failed(sem);
89} 101}
90 102
103static inline void __down_write(struct rw_semaphore *sem)
104{
105 __down_write_nested(sem, 0);
106}
107
91static inline int __down_write_trylock(struct rw_semaphore *sem) 108static inline int __down_write_trylock(struct rw_semaphore *sem)
92{ 109{
93 int tmp; 110 int tmp;
diff --git a/include/asm-powerpc/spinlock.h b/include/asm-powerpc/spinlock.h
index cc4cfceac67c..258c93993190 100644
--- a/include/asm-powerpc/spinlock.h
+++ b/include/asm-powerpc/spinlock.h
@@ -19,6 +19,7 @@
19 * 19 *
20 * (the type definitions are in asm/spinlock_types.h) 20 * (the type definitions are in asm/spinlock_types.h)
21 */ 21 */
22#include <linux/irqflags.h>
22#ifdef CONFIG_PPC64 23#ifdef CONFIG_PPC64
23#include <asm/paca.h> 24#include <asm/paca.h>
24#include <asm/hvcall.h> 25#include <asm/hvcall.h>