diff options
| -rw-r--r-- | drivers/acpi/apei/apei-base.c | 26 | ||||
| -rw-r--r-- | drivers/acpi/apei/apei-internal.h | 2 | ||||
| -rw-r--r-- | drivers/acpi/apei/ghes.c | 10 | 
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)  	return dapei;  }  EXPORT_SYMBOL_GPL(apei_get_debugfs_dir); + +int apei_osc_setup(void) +{ +	static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c"; +	acpi_handle handle; +	u32 capbuf[3]; +	struct acpi_osc_context context = { +		.uuid_str	= whea_uuid_str, +		.rev		= 1, +		.cap.length	= sizeof(capbuf), +		.cap.pointer	= capbuf, +	}; + +	capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; +	capbuf[OSC_SUPPORT_TYPE] = 0; +	capbuf[OSC_CONTROL_TYPE] = 0; + +	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)) +	    || ACPI_FAILURE(acpi_run_osc(handle, &context))) +		return -EIO; +	else { +		kfree(context.ret.pointer); +		return 0; +	} +} +EXPORT_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,  			const struct acpi_hest_generic_status *estatus);  int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);  int apei_estatus_check(const struct acpi_hest_generic_status *estatus); + +int apei_osc_setup(void);  #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)  	if (rc)  		goto err_ioremap_exit; +	rc = apei_osc_setup(); +	if (rc == 0 && osc_sb_apei_support_acked) +		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n"); +	else if (rc == 0 && !osc_sb_apei_support_acked) +		pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n"); +	else if (rc && osc_sb_apei_support_acked) +		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n"); +	else +		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n"); +  	return 0;  err_ioremap_exit:  	ghes_ioremap_exit(); | 
