From patchwork Mon Nov 30 08:13:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai-Heng Feng X-Patchwork-Id: 1408058 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CkyfT3JDBz9sTv; Mon, 30 Nov 2020 19:13:21 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1kjeJB-00013A-Dt; Mon, 30 Nov 2020 08:13:17 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kjeJ9-00012M-3u for kernel-team@lists.ubuntu.com; Mon, 30 Nov 2020 08:13:15 +0000 Received: from 220-133-187-190.hinet-ip.hinet.net ([220.133.187.190] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kjeJ8-0005oP-8v for kernel-team@lists.ubuntu.com; Mon, 30 Nov 2020 08:13:14 +0000 From: Kai-Heng Feng To: kernel-team@lists.ubuntu.com Subject: [PATCH 2/2] PM: ACPI: Refresh wakeup device power configuration every time Date: Mon, 30 Nov 2020 16:13:02 +0800 Message-Id: <20201130081302.372240-3-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201130081302.372240-1-kai.heng.feng@canonical.com> References: <20201130081302.372240-1-kai.heng.feng@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: "Rafael J. Wysocki" BugLink: https://bugs.launchpad.net/bugs/1906229 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 Reported-by: Kai-Heng Feng Tested-by: Kai-Heng Feng Reviewed-by: Mika Westerberg (cherry picked from commit 7400906166b4bbbca79d4e44094dddeefbb6ecd5 linux-next) Signed-off-by: Kai-Heng Feng --- drivers/acpi/device_pm.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index ef77dbcaf58f..3586434d0ded 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -757,16 +757,26 @@ static int __acpi_device_wakeup_enable(struct acpi_device *adev, mutex_lock(&acpi_wakeup_lock); - if (wakeup->enable_count >= INT_MAX) { - acpi_handle_info(adev->handle, "Wakeup enable count out of bounds!\n"); - goto out; - } + /* + * If the device wakeup power is already enabled, disable it and enable + * it again in case it depends on the configuration of subordinate + * devices and the conditions have changed since it was enabled last + * time. + */ if (wakeup->enable_count > 0) - goto inc; + acpi_disable_wakeup_device_power(adev); error = acpi_enable_wakeup_device_power(adev, target_state); - if (error) + if (error) { + if (wakeup->enable_count > 0) { + acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); + wakeup->enable_count = 0; + } goto out; + } + + if (wakeup->enable_count > 0) + goto inc; status = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); if (ACPI_FAILURE(status)) { @@ -779,7 +789,10 @@ static int __acpi_device_wakeup_enable(struct acpi_device *adev, (unsigned int)wakeup->gpe_number); inc: - wakeup->enable_count++; + if (wakeup->enable_count < INT_MAX) + wakeup->enable_count++; + else + acpi_handle_info(adev->handle, "Wakeup enable count out of bounds!\n"); out: mutex_unlock(&acpi_wakeup_lock);