Commit | Line | Data |
---|---|---|
34d97e07 BH |
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 */ |