Commit 94df82fe authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'acpi-6.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI fixes from Rafael Wysocki:
 "These fix a recent regression in the ACPI EC driver and make system
  suspend work on multiple platforms where StorageD3Enable _DSD is
  missing in the ACPI tables.

  Specifics:

   - Make the ACPI EC driver directly evaluate an "orphan" _REG method
     under the EC device, if present, which stopped being evaluated
     after the driver had started to install its EC address space
     handler at the root of the ACPI namespace (Rafael Wysocki)

   - Make more devices put NVMe storage devices into D3 at suspend to
     work around missing StorageD3Enable _DSD in the BIOS (Mario
     Limonciello)"

* tag 'acpi-6.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: EC: Evaluate orphan _REG under EC device
  ACPI: x86: Force StorageD3Enable on more products
parents cee84c0b 04f82fbb
...@@ -191,6 +191,10 @@ void ...@@ -191,6 +191,10 @@ void
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
acpi_adr_space_type space_id, u32 function); acpi_adr_space_type space_id, u32 function);
void
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *node,
acpi_adr_space_type space_id);
acpi_status acpi_status
acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function); acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function);
......
...@@ -20,10 +20,6 @@ extern u8 acpi_gbl_default_address_spaces[]; ...@@ -20,10 +20,6 @@ extern u8 acpi_gbl_default_address_spaces[];
/* Local prototypes */ /* Local prototypes */
static void
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
acpi_adr_space_type space_id);
static acpi_status static acpi_status
acpi_ev_reg_run(acpi_handle obj_handle, acpi_ev_reg_run(acpi_handle obj_handle,
u32 level, void *context, void **return_value); u32 level, void *context, void **return_value);
...@@ -818,7 +814,7 @@ acpi_ev_reg_run(acpi_handle obj_handle, ...@@ -818,7 +814,7 @@ acpi_ev_reg_run(acpi_handle obj_handle,
* *
******************************************************************************/ ******************************************************************************/
static void void
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
acpi_adr_space_type space_id) acpi_adr_space_type space_id)
{ {
......
...@@ -306,3 +306,57 @@ acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id) ...@@ -306,3 +306,57 @@ acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
} }
ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods) ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods)
/*******************************************************************************
*
* FUNCTION: acpi_execute_orphan_reg_method
*
* PARAMETERS: device - Handle for the device
* space_id - The address space ID
*
* RETURN: Status
*
* DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI
* device. This is a _REG method that has no corresponding region
* within the device's scope.
*
******************************************************************************/
acpi_status
acpi_execute_orphan_reg_method(acpi_handle device, acpi_adr_space_type space_id)
{
struct acpi_namespace_node *node;
acpi_status status;
ACPI_FUNCTION_TRACE(acpi_execute_orphan_reg_method);
/* Parameter validation */
if (!device) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Convert and validate the device handle */
node = acpi_ns_validate_handle(device);
if (node) {
/*
* If an "orphan" _REG method is present in the device's scope
* for the given address space ID, run it.
*/
acpi_ev_execute_orphan_reg_method(node, space_id);
} else {
status = AE_BAD_PARAMETER;
}
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL(acpi_execute_orphan_reg_method)
...@@ -1507,6 +1507,9 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device, ...@@ -1507,6 +1507,9 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) { if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC); acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC);
if (scope_handle != ec->handle)
acpi_execute_orphan_reg_method(ec->handle, ACPI_ADR_SPACE_EC);
set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags); set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
} }
......
...@@ -206,16 +206,16 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s ...@@ -206,16 +206,16 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s
} }
/* /*
* AMD systems from Renoir and Lucienne *require* that the NVME controller * AMD systems from Renoir onwards *require* that the NVME controller
* is put into D3 over a Modern Standby / suspend-to-idle cycle. * is put into D3 over a Modern Standby / suspend-to-idle cycle.
* *
* This is "typically" accomplished using the `StorageD3Enable` * This is "typically" accomplished using the `StorageD3Enable`
* property in the _DSD that is checked via the `acpi_storage_d3` function * property in the _DSD that is checked via the `acpi_storage_d3` function
* but this property was introduced after many of these systems launched * but some OEM systems still don't have it in their BIOS.
* and most OEM systems don't have it in their BIOS.
* *
* The Microsoft documentation for StorageD3Enable mentioned that Windows has * The Microsoft documentation for StorageD3Enable mentioned that Windows has
* a hardcoded allowlist for D3 support, which was used for these platforms. * a hardcoded allowlist for D3 support as well as a registry key to override
* the BIOS, which has been used for these cases.
* *
* This allows quirking on Linux in a similar fashion. * This allows quirking on Linux in a similar fashion.
* *
...@@ -228,19 +228,15 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s ...@@ -228,19 +228,15 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s
* https://bugzilla.kernel.org/show_bug.cgi?id=216773 * https://bugzilla.kernel.org/show_bug.cgi?id=216773
* https://bugzilla.kernel.org/show_bug.cgi?id=217003 * https://bugzilla.kernel.org/show_bug.cgi?id=217003
* 2) On at least one HP system StorageD3Enable is missing on the second NVME * 2) On at least one HP system StorageD3Enable is missing on the second NVME
disk in the system. * disk in the system.
* 3) On at least one HP Rembrandt system StorageD3Enable is missing on the only
* NVME device.
*/ */
static const struct x86_cpu_id storage_d3_cpu_ids[] = {
X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 24, NULL), /* Picasso */
X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL), /* Renoir */
X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL), /* Lucienne */
X86_MATCH_VENDOR_FAM_MODEL(AMD, 25, 80, NULL), /* Cezanne */
{}
};
bool force_storage_d3(void) bool force_storage_d3(void)
{ {
return x86_match_cpu(storage_d3_cpu_ids); if (!cpu_feature_enabled(X86_FEATURE_ZEN))
return false;
return acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0;
} }
/* /*
......
...@@ -662,6 +662,10 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status ...@@ -662,6 +662,10 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
acpi_execute_reg_methods(acpi_handle device, acpi_execute_reg_methods(acpi_handle device,
acpi_adr_space_type acpi_adr_space_type
space_id)) space_id))
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
acpi_execute_orphan_reg_method(acpi_handle device,
acpi_adr_space_type
space_id))
ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_EXTERNAL_RETURN_STATUS(acpi_status
acpi_remove_address_space_handler(acpi_handle acpi_remove_address_space_handler(acpi_handle
device, device,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment