diff options
Diffstat (limited to 'arch/powerpc/kernel/idle_book3e.S')
-rw-r--r-- | arch/powerpc/kernel/idle_book3e.S | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/idle_book3e.S b/arch/powerpc/kernel/idle_book3e.S new file mode 100644 index 000000000000..16c002d6bdf1 --- /dev/null +++ b/arch/powerpc/kernel/idle_book3e.S | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * Copyright 2010 IBM Corp, Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
3 | * | ||
4 | * Generic idle routine for Book3E processors | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/threads.h> | ||
13 | #include <asm/reg.h> | ||
14 | #include <asm/ppc_asm.h> | ||
15 | #include <asm/asm-offsets.h> | ||
16 | #include <asm/ppc-opcode.h> | ||
17 | #include <asm/processor.h> | ||
18 | #include <asm/thread_info.h> | ||
19 | |||
20 | /* 64-bit version only for now */ | ||
21 | #ifdef CONFIG_PPC64 | ||
22 | |||
23 | _GLOBAL(book3e_idle) | ||
24 | /* Save LR for later */ | ||
25 | mflr r0 | ||
26 | std r0,16(r1) | ||
27 | |||
28 | /* Hard disable interrupts */ | ||
29 | wrteei 0 | ||
30 | |||
31 | /* Now check if an interrupt came in while we were soft disabled | ||
32 | * since we may otherwise lose it (doorbells etc...). We know | ||
33 | * that since PACAHARDIRQEN will have been cleared in that case. | ||
34 | */ | ||
35 | lbz r3,PACAHARDIRQEN(r13) | ||
36 | cmpwi cr0,r3,0 | ||
37 | beqlr | ||
38 | |||
39 | /* Now we are going to mark ourselves as soft and hard enables in | ||
40 | * order to be able to take interrupts while asleep. We inform lockdep | ||
41 | * of that. We don't actually turn interrupts on just yet tho. | ||
42 | */ | ||
43 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
44 | stdu r1,-128(r1) | ||
45 | bl .trace_hardirqs_on | ||
46 | #endif | ||
47 | li r0,1 | ||
48 | stb r0,PACASOFTIRQEN(r13) | ||
49 | stb r0,PACAHARDIRQEN(r13) | ||
50 | |||
51 | /* Interrupts will make use return to LR, so get something we want | ||
52 | * in there | ||
53 | */ | ||
54 | bl 1f | ||
55 | |||
56 | /* Hard disable interrupts again */ | ||
57 | wrteei 0 | ||
58 | |||
59 | /* Mark them off again in the PACA as well */ | ||
60 | li r0,0 | ||
61 | stb r0,PACASOFTIRQEN(r13) | ||
62 | stb r0,PACAHARDIRQEN(r13) | ||
63 | |||
64 | /* Tell lockdep about it */ | ||
65 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
66 | bl .trace_hardirqs_off | ||
67 | addi r1,r1,128 | ||
68 | #endif | ||
69 | ld r0,16(r1) | ||
70 | mtlr r0 | ||
71 | blr | ||
72 | |||
73 | 1: /* Let's set the _TLF_NAPPING flag so interrupts make us return | ||
74 | * to the right spot | ||
75 | */ | ||
76 | clrrdi r11,r1,THREAD_SHIFT | ||
77 | ld r10,TI_LOCAL_FLAGS(r11) | ||
78 | ori r10,r10,_TLF_NAPPING | ||
79 | std r10,TI_LOCAL_FLAGS(r11) | ||
80 | |||
81 | /* We can now re-enable hard interrupts and go to sleep */ | ||
82 | wrteei 1 | ||
83 | 1: PPC_WAIT(0) | ||
84 | b 1b | ||
85 | |||
86 | #endif /* CONFIG_PPC64 */ | ||