aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2014-07-29 09:10:13 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-08-05 02:33:57 -0400
commitbbdb760d8d477f0a57e3f2394e352ccc6f5e9961 (patch)
tree2509d82ecf8bcd2f7723116e91869debc3b9cbfb /arch/powerpc/kernel
parent0ef95b411e73d8789100d017c02c1329c5055802 (diff)
powerpc/book3s: handle HMIs for cpus in nap mode.
HMIs are thread specific and can come while thread is in sleep/nap mode. Hence with SMT=off mode we can receive HMIs on sleeping threads. For interrupt received in nap mode, cpu wakes up at system reset vector, clears the interrupt and go back to nap mode again. But HMIs are sticky and they keep happening until we clear reason bits from HMER. Hence add a special check for HMI in reset vector (through power7_wakeup_* functions) and invoke opal call to handle HMI. Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/idle_power7.S32
1 files changed, 32 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index 5cf3d367190d..06305f653ab1 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -135,10 +135,36 @@ _GLOBAL(power7_sleep)
135 b power7_powersave_common 135 b power7_powersave_common
136 /* No return */ 136 /* No return */
137 137
138#define CHECK_HMI_INTERRUPT \
139 mfspr r0,SPRN_SRR1; \
140BEGIN_FTR_SECTION_NESTED(66); \
141 rlwinm r0,r0,45-31,0xf; /* extract wake reason field (P8) */ \
142FTR_SECTION_ELSE_NESTED(66); \
143 rlwinm r0,r0,45-31,0xe; /* P7 wake reason field is 3 bits */ \
144ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_ARCH_207S, 66); \
145 cmpwi r0,0xa; /* Hypervisor maintenance ? */ \
146 bne 20f; \
147 /* Invoke opal call to handle hmi */ \
148 ld r2,PACATOC(r13); \
149 ld r1,PACAR1(r13); \
150 std r3,ORIG_GPR3(r1); /* Save original r3 */ \
151 li r0,OPAL_HANDLE_HMI; \
152 LOAD_REG_ADDR(r11,opal); \
153 ld r12,8(r11); \
154 ld r2,0(r11); \
155 mtctr r12; \
156 bctrl; \
157 ld r3,ORIG_GPR3(r1); /* Restore original r3 */ \
15820: nop;
159
160
138_GLOBAL(power7_wakeup_tb_loss) 161_GLOBAL(power7_wakeup_tb_loss)
139 ld r2,PACATOC(r13); 162 ld r2,PACATOC(r13);
140 ld r1,PACAR1(r13) 163 ld r1,PACAR1(r13)
141 164
165BEGIN_FTR_SECTION
166 CHECK_HMI_INTERRUPT
167END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
142 /* Time base re-sync */ 168 /* Time base re-sync */
143 li r0,OPAL_RESYNC_TIMEBASE 169 li r0,OPAL_RESYNC_TIMEBASE
144 LOAD_REG_ADDR(r11,opal); 170 LOAD_REG_ADDR(r11,opal);
@@ -163,6 +189,9 @@ _GLOBAL(power7_wakeup_tb_loss)
163 189
164_GLOBAL(power7_wakeup_loss) 190_GLOBAL(power7_wakeup_loss)
165 ld r1,PACAR1(r13) 191 ld r1,PACAR1(r13)
192BEGIN_FTR_SECTION
193 CHECK_HMI_INTERRUPT
194END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
166 REST_NVGPRS(r1) 195 REST_NVGPRS(r1)
167 REST_GPR(2, r1) 196 REST_GPR(2, r1)
168 ld r3,_CCR(r1) 197 ld r3,_CCR(r1)
@@ -178,6 +207,9 @@ _GLOBAL(power7_wakeup_noloss)
178 lbz r0,PACA_NAPSTATELOST(r13) 207 lbz r0,PACA_NAPSTATELOST(r13)
179 cmpwi r0,0 208 cmpwi r0,0
180 bne power7_wakeup_loss 209 bne power7_wakeup_loss
210BEGIN_FTR_SECTION
211 CHECK_HMI_INTERRUPT
212END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
181 ld r1,PACAR1(r13) 213 ld r1,PACAR1(r13)
182 ld r4,_MSR(r1) 214 ld r4,_MSR(r1)
183 ld r5,_NIP(r1) 215 ld r5,_NIP(r1)