| .. | .. |
|---|
| 1140 | 1140 | return true; |
|---|
| 1141 | 1141 | } |
|---|
| 1142 | 1142 | |
|---|
| 1143 | | -static int __init sdei_init(void) |
|---|
| 1143 | +void __init sdei_init(void) |
|---|
| 1144 | 1144 | { |
|---|
| 1145 | 1145 | struct platform_device *pdev; |
|---|
| 1146 | 1146 | int ret; |
|---|
| 1147 | 1147 | |
|---|
| 1148 | 1148 | ret = platform_driver_register(&sdei_driver); |
|---|
| 1149 | 1149 | if (ret || !sdei_present_acpi()) |
|---|
| 1150 | | - return ret; |
|---|
| 1150 | + return; |
|---|
| 1151 | 1151 | |
|---|
| 1152 | 1152 | pdev = platform_device_register_simple(sdei_driver.driver.name, |
|---|
| 1153 | 1153 | 0, NULL, 0); |
|---|
| .. | .. |
|---|
| 1157 | 1157 | pr_info("Failed to register ACPI:SDEI platform device %d\n", |
|---|
| 1158 | 1158 | ret); |
|---|
| 1159 | 1159 | } |
|---|
| 1160 | | - |
|---|
| 1161 | | - return ret; |
|---|
| 1162 | 1160 | } |
|---|
| 1163 | | - |
|---|
| 1164 | | -/* |
|---|
| 1165 | | - * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register |
|---|
| 1166 | | - * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised |
|---|
| 1167 | | - * by device_initcall(). We want to be called in the middle. |
|---|
| 1168 | | - */ |
|---|
| 1169 | | -subsys_initcall_sync(sdei_init); |
|---|
| 1170 | 1161 | |
|---|
| 1171 | 1162 | int sdei_event_handler(struct pt_regs *regs, |
|---|
| 1172 | 1163 | struct sdei_registered_event *arg) |
|---|
| .. | .. |
|---|
| 1195 | 1186 | return err; |
|---|
| 1196 | 1187 | } |
|---|
| 1197 | 1188 | NOKPROBE_SYMBOL(sdei_event_handler); |
|---|
| 1189 | + |
|---|
| 1190 | +void sdei_handler_abort(void) |
|---|
| 1191 | +{ |
|---|
| 1192 | + /* |
|---|
| 1193 | + * If the crash happened in an SDEI event handler then we need to |
|---|
| 1194 | + * finish the handler with the firmware so that we can have working |
|---|
| 1195 | + * interrupts in the crash kernel. |
|---|
| 1196 | + */ |
|---|
| 1197 | + if (__this_cpu_read(sdei_active_critical_event)) { |
|---|
| 1198 | + pr_warn("still in SDEI critical event context, attempting to finish handler.\n"); |
|---|
| 1199 | + __sdei_handler_abort(); |
|---|
| 1200 | + __this_cpu_write(sdei_active_critical_event, NULL); |
|---|
| 1201 | + } |
|---|
| 1202 | + if (__this_cpu_read(sdei_active_normal_event)) { |
|---|
| 1203 | + pr_warn("still in SDEI normal event context, attempting to finish handler.\n"); |
|---|
| 1204 | + __sdei_handler_abort(); |
|---|
| 1205 | + __this_cpu_write(sdei_active_normal_event, NULL); |
|---|
| 1206 | + } |
|---|
| 1207 | +} |
|---|