aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/apei
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2011-07-13 01:14:21 -0400
committerLen Brown <len.brown@intel.com>2011-07-13 23:38:49 -0400
commit9fb0bfe1408d5506b7b83d13d1eed573fd71d67d (patch)
tree51700355f453ab47de4bd799a4468c030db6e088 /drivers/acpi/apei
parenteccddd32ced0df8f9130024157bf8d37df860d76 (diff)
ACPI, APEI, Add WHEA _OSC support
APEI firmware first mode must be turned on explicitly on some machines, otherwise there may be no GHES hardware error record for hardware error notification. APEI bit in generic _OSC call can be used to do that, but on some machine, a special WHEA _OSC call must be used. This patch adds the support to that WHEA _OSC call. Signed-off-by: Huang Ying <ying.huang@intel.com> Reviewed-by: Andi Kleen <ak@linux.intel.com> Reviewed-by: Matthew Garrett <mjg@redhat.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/apei')
-rw-r--r--drivers/acpi/apei/apei-base.c26
-rw-r--r--drivers/acpi/apei/apei-internal.h2
-rw-r--r--drivers/acpi/apei/ghes.c10
3 files changed, 38 insertions, 0 deletions
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index 0714194229da..8041248fce9b 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -604,3 +604,29 @@ struct dentry *apei_get_debugfs_dir(void)
604 return dapei; 604 return dapei;
605} 605}
606EXPORT_SYMBOL_GPL(apei_get_debugfs_dir); 606EXPORT_SYMBOL_GPL(apei_get_debugfs_dir);
607
608int apei_osc_setup(void)
609{
610 static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c";
611 acpi_handle handle;
612 u32 capbuf[3];
613 struct acpi_osc_context context = {
614 .uuid_str = whea_uuid_str,
615 .rev = 1,
616 .cap.length = sizeof(capbuf),
617 .cap.pointer = capbuf,
618 };
619
620 capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
621 capbuf[OSC_SUPPORT_TYPE] = 0;
622 capbuf[OSC_CONTROL_TYPE] = 0;
623
624 if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))
625 || ACPI_FAILURE(acpi_run_osc(handle, &context)))
626 return -EIO;
627 else {
628 kfree(context.ret.pointer);
629 return 0;
630 }
631}
632EXPORT_SYMBOL_GPL(apei_osc_setup);
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
index f286cf753f32..f57050e7a5e7 100644
--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -124,4 +124,6 @@ void apei_estatus_print(const char *pfx,
124 const struct acpi_hest_generic_status *estatus); 124 const struct acpi_hest_generic_status *estatus);
125int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); 125int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
126int apei_estatus_check(const struct acpi_hest_generic_status *estatus); 126int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
127
128int apei_osc_setup(void);
127#endif 129#endif
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index b142b94bf8b2..b1390a61cde1 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -681,6 +681,16 @@ static int __init ghes_init(void)
681 if (rc) 681 if (rc)
682 goto err_ioremap_exit; 682 goto err_ioremap_exit;
683 683
684 rc = apei_osc_setup();
685 if (rc == 0 && osc_sb_apei_support_acked)
686 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n");
687 else if (rc == 0 && !osc_sb_apei_support_acked)
688 pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n");
689 else if (rc && osc_sb_apei_support_acked)
690 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
691 else
692 pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
693
684 return 0; 694 return 0;
685err_ioremap_exit: 695err_ioremap_exit:
686 ghes_ioremap_exit(); 696 ghes_ioremap_exit();