Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbdb760d authored by Mahesh Salgaonkar's avatar Mahesh Salgaonkar Committed by Benjamin Herrenschmidt
Browse files

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: default avatarMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 0ef95b41
Loading
Loading
Loading
Loading
+32 −0
Original line number Original line Diff line number Diff line
@@ -135,10 +135,36 @@ _GLOBAL(power7_sleep)
	b	power7_powersave_common
	b	power7_powersave_common
	/* No return */
	/* No return */


#define CHECK_HMI_INTERRUPT						\
	mfspr	r0,SPRN_SRR1;						\
BEGIN_FTR_SECTION_NESTED(66);						\
	rlwinm	r0,r0,45-31,0xf;  /* extract wake reason field (P8) */	\
FTR_SECTION_ELSE_NESTED(66);						\
	rlwinm	r0,r0,45-31,0xe;  /* P7 wake reason field is 3 bits */	\
ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_ARCH_207S, 66);		\
	cmpwi	r0,0xa;			/* Hypervisor maintenance ? */	\
	bne	20f;							\
	/* Invoke opal call to handle hmi */				\
	ld	r2,PACATOC(r13);					\
	ld	r1,PACAR1(r13);						\
	std	r3,ORIG_GPR3(r1);	/* Save original r3 */		\
	li	r0,OPAL_HANDLE_HMI;					\
	LOAD_REG_ADDR(r11,opal);					\
	ld	r12,8(r11);						\
	ld	r2,0(r11);						\
	mtctr	r12;							\
	bctrl;								\
	ld	r3,ORIG_GPR3(r1);	/* Restore original r3 */	\
20:	nop;


_GLOBAL(power7_wakeup_tb_loss)
_GLOBAL(power7_wakeup_tb_loss)
	ld	r2,PACATOC(r13);
	ld	r2,PACATOC(r13);
	ld	r1,PACAR1(r13)
	ld	r1,PACAR1(r13)


BEGIN_FTR_SECTION
	CHECK_HMI_INTERRUPT
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
	/* Time base re-sync */
	/* Time base re-sync */
	li	r0,OPAL_RESYNC_TIMEBASE
	li	r0,OPAL_RESYNC_TIMEBASE
	LOAD_REG_ADDR(r11,opal);
	LOAD_REG_ADDR(r11,opal);
@@ -163,6 +189,9 @@ _GLOBAL(power7_wakeup_tb_loss)


_GLOBAL(power7_wakeup_loss)
_GLOBAL(power7_wakeup_loss)
	ld	r1,PACAR1(r13)
	ld	r1,PACAR1(r13)
BEGIN_FTR_SECTION
	CHECK_HMI_INTERRUPT
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
	REST_NVGPRS(r1)
	REST_NVGPRS(r1)
	REST_GPR(2, r1)
	REST_GPR(2, r1)
	ld	r3,_CCR(r1)
	ld	r3,_CCR(r1)
@@ -178,6 +207,9 @@ _GLOBAL(power7_wakeup_noloss)
	lbz	r0,PACA_NAPSTATELOST(r13)
	lbz	r0,PACA_NAPSTATELOST(r13)
	cmpwi	r0,0
	cmpwi	r0,0
	bne	power7_wakeup_loss
	bne	power7_wakeup_loss
BEGIN_FTR_SECTION
	CHECK_HMI_INTERRUPT
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
	ld	r1,PACAR1(r13)
	ld	r1,PACAR1(r13)
	ld	r4,_MSR(r1)
	ld	r4,_MSR(r1)
	ld	r5,_NIP(r1)
	ld	r5,_NIP(r1)