mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 17:41:44 +00:00
[S390] Use diagnose 308 for system reset
The diagnose 308 call is the prefered method for clearing all ongoing I/O. Therefore if it is available we use it instead of doing a manual reset. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
This commit is contained in:
parent
ef1daec8da
commit
9dc7356ee1
@ -167,5 +167,6 @@ enum diag308_rc {
|
||||
};
|
||||
|
||||
extern int diag308(unsigned long subcode, void *addr);
|
||||
extern void diag308_reset(void);
|
||||
|
||||
#endif /* _ASM_S390_IPL_H */
|
||||
|
@ -76,6 +76,42 @@ s390_base_pgm_handler_fn:
|
||||
.quad 0
|
||||
.previous
|
||||
|
||||
#
|
||||
# Calls diag 308 subcode 1 and continues execution
|
||||
#
|
||||
# The following conditions must be ensured before calling this function:
|
||||
# * Prefix register = 0
|
||||
# * Lowcore protection is disabled
|
||||
#
|
||||
ENTRY(diag308_reset)
|
||||
larl %r4,.Lctlregs # Save control registers
|
||||
stctg %c0,%c15,0(%r4)
|
||||
larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0
|
||||
lghi %r3,0
|
||||
lg %r4,0(%r4) # Save PSW
|
||||
sturg %r4,%r3 # Use sturg, because of large pages
|
||||
lghi %r1,1
|
||||
diag %r1,%r1,0x308
|
||||
.Lrestart_part2:
|
||||
lhi %r0,0 # Load r0 with zero
|
||||
lhi %r1,2 # Use mode 2 = ESAME (dump)
|
||||
sigp %r1,%r0,0x12 # Switch to ESAME mode
|
||||
sam64 # Switch to 64 bit addressing mode
|
||||
larl %r4,.Lctlregs # Restore control registers
|
||||
lctlg %c0,%c15,0(%r4)
|
||||
br %r14
|
||||
.align 16
|
||||
.Lrestart_psw:
|
||||
.long 0x00080000,0x80000000 + .Lrestart_part2
|
||||
|
||||
.section .bss
|
||||
.align 8
|
||||
.Lctlregs:
|
||||
.rept 16
|
||||
.quad 0
|
||||
.endr
|
||||
.previous
|
||||
|
||||
#else /* CONFIG_64BIT */
|
||||
|
||||
ENTRY(s390_base_mcck_handler)
|
||||
|
@ -1996,6 +1996,12 @@ static void do_reset_calls(void)
|
||||
{
|
||||
struct reset_call *reset;
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
if (diag308_set_works) {
|
||||
diag308_reset();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
list_for_each_entry(reset, &rcall, list)
|
||||
reset->fn();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user