diff options
| -rw-r--r-- | drivers/acpi/acpi_extlog.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index a6869e110ce5..5d33c5415405 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <acpi/acpi_bus.h> | 12 | #include <acpi/acpi_bus.h> |
| 13 | #include <linux/cper.h> | 13 | #include <linux/cper.h> |
| 14 | #include <linux/ratelimit.h> | 14 | #include <linux/ratelimit.h> |
| 15 | #include <linux/edac.h> | ||
| 15 | #include <asm/cpu.h> | 16 | #include <asm/cpu.h> |
| 16 | #include <asm/mce.h> | 17 | #include <asm/mce.h> |
| 17 | 18 | ||
| @@ -43,6 +44,8 @@ struct extlog_l1_head { | |||
| 43 | u8 rev1[12]; | 44 | u8 rev1[12]; |
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 47 | static int old_edac_report_status; | ||
| 48 | |||
| 46 | static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295"; | 49 | static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295"; |
| 47 | 50 | ||
| 48 | /* L1 table related physical address */ | 51 | /* L1 table related physical address */ |
| @@ -150,7 +153,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, | |||
| 150 | 153 | ||
| 151 | rc = print_extlog_rcd(NULL, (struct acpi_generic_status *)elog_buf, cpu); | 154 | rc = print_extlog_rcd(NULL, (struct acpi_generic_status *)elog_buf, cpu); |
| 152 | 155 | ||
| 153 | return NOTIFY_DONE; | 156 | return NOTIFY_STOP; |
| 154 | } | 157 | } |
| 155 | 158 | ||
| 156 | static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret) | 159 | static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret) |
| @@ -231,8 +234,12 @@ static int __init extlog_init(void) | |||
| 231 | u64 cap; | 234 | u64 cap; |
| 232 | int rc; | 235 | int rc; |
| 233 | 236 | ||
| 234 | rc = -ENODEV; | 237 | if (get_edac_report_status() == EDAC_REPORTING_FORCE) { |
| 238 | pr_warn("Not loading eMCA, error reporting force-enabled through EDAC.\n"); | ||
| 239 | return -EPERM; | ||
| 240 | } | ||
| 235 | 241 | ||
| 242 | rc = -ENODEV; | ||
| 236 | rdmsrl(MSR_IA32_MCG_CAP, cap); | 243 | rdmsrl(MSR_IA32_MCG_CAP, cap); |
| 237 | if (!(cap & MCG_ELOG_P)) | 244 | if (!(cap & MCG_ELOG_P)) |
| 238 | return rc; | 245 | return rc; |
| @@ -287,6 +294,12 @@ static int __init extlog_init(void) | |||
| 287 | if (elog_buf == NULL) | 294 | if (elog_buf == NULL) |
| 288 | goto err_release_elog; | 295 | goto err_release_elog; |
| 289 | 296 | ||
| 297 | /* | ||
| 298 | * eMCA event report method has higher priority than EDAC method, | ||
| 299 | * unless EDAC event report method is mandatory. | ||
| 300 | */ | ||
| 301 | old_edac_report_status = get_edac_report_status(); | ||
| 302 | set_edac_report_status(EDAC_REPORTING_DISABLED); | ||
| 290 | mce_register_decode_chain(&extlog_mce_dec); | 303 | mce_register_decode_chain(&extlog_mce_dec); |
| 291 | /* enable OS to be involved to take over management from BIOS */ | 304 | /* enable OS to be involved to take over management from BIOS */ |
| 292 | ((struct extlog_l1_head *)extlog_l1_addr)->flags |= FLAG_OS_OPTIN; | 305 | ((struct extlog_l1_head *)extlog_l1_addr)->flags |= FLAG_OS_OPTIN; |
| @@ -308,6 +321,7 @@ err: | |||
| 308 | 321 | ||
| 309 | static void __exit extlog_exit(void) | 322 | static void __exit extlog_exit(void) |
| 310 | { | 323 | { |
| 324 | set_edac_report_status(old_edac_report_status); | ||
| 311 | mce_unregister_decode_chain(&extlog_mce_dec); | 325 | mce_unregister_decode_chain(&extlog_mce_dec); |
| 312 | ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; | 326 | ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; |
| 313 | if (extlog_l1_addr) | 327 | if (extlog_l1_addr) |
