diff options
Diffstat (limited to 'arch/s390/kernel/ipl.c')
-rw-r--r-- | arch/s390/kernel/ipl.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index ec127826f221..77f4aff630fe 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/cpcmd.h> | 19 | #include <asm/cpcmd.h> |
20 | #include <asm/cio.h> | 20 | #include <asm/cio.h> |
21 | #include <asm/ebcdic.h> | 21 | #include <asm/ebcdic.h> |
22 | #include <asm/reset.h> | ||
22 | 23 | ||
23 | #define IPL_PARM_BLOCK_VERSION 0 | 24 | #define IPL_PARM_BLOCK_VERSION 0 |
24 | #define LOADPARM_LEN 8 | 25 | #define LOADPARM_LEN 8 |
@@ -1024,3 +1025,56 @@ static int __init s390_ipl_init(void) | |||
1024 | } | 1025 | } |
1025 | 1026 | ||
1026 | __initcall(s390_ipl_init); | 1027 | __initcall(s390_ipl_init); |
1028 | |||
1029 | static LIST_HEAD(rcall); | ||
1030 | static DEFINE_MUTEX(rcall_mutex); | ||
1031 | |||
1032 | void register_reset_call(struct reset_call *reset) | ||
1033 | { | ||
1034 | mutex_lock(&rcall_mutex); | ||
1035 | list_add(&reset->list, &rcall); | ||
1036 | mutex_unlock(&rcall_mutex); | ||
1037 | } | ||
1038 | EXPORT_SYMBOL_GPL(register_reset_call); | ||
1039 | |||
1040 | void unregister_reset_call(struct reset_call *reset) | ||
1041 | { | ||
1042 | mutex_lock(&rcall_mutex); | ||
1043 | list_del(&reset->list); | ||
1044 | mutex_unlock(&rcall_mutex); | ||
1045 | } | ||
1046 | EXPORT_SYMBOL_GPL(unregister_reset_call); | ||
1047 | |||
1048 | static void do_reset_calls(void) | ||
1049 | { | ||
1050 | struct reset_call *reset; | ||
1051 | |||
1052 | list_for_each_entry(reset, &rcall, list) | ||
1053 | reset->fn(); | ||
1054 | } | ||
1055 | |||
1056 | extern void reset_mcck_handler(void); | ||
1057 | |||
1058 | void s390_reset_system(void) | ||
1059 | { | ||
1060 | struct _lowcore *lc; | ||
1061 | |||
1062 | /* Disable all interrupts/machine checks */ | ||
1063 | __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK); | ||
1064 | |||
1065 | /* Stack for interrupt/machine check handler */ | ||
1066 | lc = (struct _lowcore *)(unsigned long) store_prefix(); | ||
1067 | lc->panic_stack = S390_lowcore.panic_stack; | ||
1068 | |||
1069 | /* Disable prefixing */ | ||
1070 | set_prefix(0); | ||
1071 | |||
1072 | /* Disable lowcore protection */ | ||
1073 | __ctl_clear_bit(0,28); | ||
1074 | |||
1075 | /* Set new machine check handler */ | ||
1076 | S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK; | ||
1077 | S390_lowcore.mcck_new_psw.addr = | ||
1078 | PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler; | ||
1079 | do_reset_calls(); | ||
1080 | } | ||