Skip to content

Commit b93b7ef

Browse files
committed
PM: ACPI: Refresh wakeup device power configuration every time
When wakeup signaling is enabled for a bridge for the second (or every next) time in a row, its existing device wakeup power configuration may not match the new conditions. For example, some devices below it may have been put into low-power states and that changes the device wakeup power conditions or similar. This causes functional problems to appear on some systems (for example, because of it the Thunderbolt port on Dell Precision 5550 cannot detect devices plugged in after it has been suspended). For this reason, modify __acpi_device_wakeup_enable() to refresh the device wakeup power configuration of the target device on every invocation, not just when it is called for that device first time in a row. Signed-off-by: Rafael J. Wysocki <[email protected]> Reported-by: Kai-Heng Feng <[email protected]> Tested-by: Kai-Heng Feng <[email protected]> Reviewed-by: Mika Westerberg <[email protected]>
1 parent 7482c5c commit b93b7ef

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

drivers/acpi/device_pm.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -757,16 +757,26 @@ static int __acpi_device_wakeup_enable(struct acpi_device *adev,
757757

758758
mutex_lock(&acpi_wakeup_lock);
759759

760-
if (wakeup->enable_count >= INT_MAX) {
761-
acpi_handle_info(adev->handle, "Wakeup enable count out of bounds!\n");
762-
goto out;
763-
}
760+
/*
761+
* If the device wakeup power is already enabled, disable it and enable
762+
* it again in case it depends on the configuration of subordinate
763+
* devices and the conditions have changed since it was enabled last
764+
* time.
765+
*/
764766
if (wakeup->enable_count > 0)
765-
goto inc;
767+
acpi_disable_wakeup_device_power(adev);
766768

767769
error = acpi_enable_wakeup_device_power(adev, target_state);
768-
if (error)
770+
if (error) {
771+
if (wakeup->enable_count > 0) {
772+
acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
773+
wakeup->enable_count = 0;
774+
}
769775
goto out;
776+
}
777+
778+
if (wakeup->enable_count > 0)
779+
goto inc;
770780

771781
status = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
772782
if (ACPI_FAILURE(status)) {
@@ -779,7 +789,10 @@ static int __acpi_device_wakeup_enable(struct acpi_device *adev,
779789
(unsigned int)wakeup->gpe_number);
780790

781791
inc:
782-
wakeup->enable_count++;
792+
if (wakeup->enable_count < INT_MAX)
793+
wakeup->enable_count++;
794+
else
795+
acpi_handle_info(adev->handle, "Wakeup enable count out of bounds!\n");
783796

784797
out:
785798
mutex_unlock(&acpi_wakeup_lock);

0 commit comments

Comments
 (0)