|
11 | 11 |
|
12 | 12 | #define pr_fmt(fmt) "ACPI: OSL: " fmt |
13 | 13 |
|
| 14 | +#include <linux/kconfig.h> |
14 | 15 | #include <linux/module.h> |
15 | 16 | #include <linux/kernel.h> |
| 17 | +#include <linux/reboot.h> |
16 | 18 | #include <linux/slab.h> |
17 | 19 | #include <linux/mm.h> |
18 | 20 | #include <linux/highmem.h> |
@@ -70,6 +72,10 @@ static bool acpi_os_initialized; |
70 | 72 | unsigned int acpi_sci_irq = INVALID_ACPI_IRQ; |
71 | 73 | bool acpi_permanent_mmap = false; |
72 | 74 |
|
| 75 | +static bool poweroff_on_fatal = true; |
| 76 | +module_param(poweroff_on_fatal, bool, 0); |
| 77 | +MODULE_PARM_DESC(poweroff_on_fatal, "Poweroff when encountering a fatal ACPI error"); |
| 78 | + |
73 | 79 | /* |
74 | 80 | * This list of permanent mappings is for memory that may be accessed from |
75 | 81 | * interrupt context, where we can't do the ioremap(). |
@@ -1381,9 +1387,20 @@ acpi_status acpi_os_notify_command_complete(void) |
1381 | 1387 |
|
1382 | 1388 | acpi_status acpi_os_signal(u32 function, void *info) |
1383 | 1389 | { |
| 1390 | + struct acpi_signal_fatal_info *fatal_info; |
| 1391 | + |
1384 | 1392 | switch (function) { |
1385 | 1393 | case ACPI_SIGNAL_FATAL: |
1386 | | - pr_err("Fatal opcode executed\n"); |
| 1394 | + fatal_info = info; |
| 1395 | + pr_emerg("Fatal error while evaluating ACPI control method\n"); |
| 1396 | + pr_emerg("Type 0x%X Code 0x%X Argument 0x%X\n", |
| 1397 | + fatal_info->type, fatal_info->code, fatal_info->argument); |
| 1398 | + |
| 1399 | + if (poweroff_on_fatal) |
| 1400 | + orderly_poweroff(true); |
| 1401 | + else |
| 1402 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); |
| 1403 | + |
1387 | 1404 | break; |
1388 | 1405 | case ACPI_SIGNAL_BREAKPOINT: |
1389 | 1406 | /* |
|
0 commit comments