From patchwork Sun Apr 29 20:44:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 155766 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 069B0B6FF1 for ; Mon, 30 Apr 2012 06:39:44 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754158Ab2D2Ujg (ORCPT ); Sun, 29 Apr 2012 16:39:36 -0400 Received: from ogre.sisk.pl ([193.178.161.156]:44489 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751674Ab2D2Uje (ORCPT ); Sun, 29 Apr 2012 16:39:34 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by ogre.sisk.pl (Postfix) with ESMTP id 115881D4EA3; Sun, 29 Apr 2012 22:01:29 +0200 (CEST) Received: from ogre.sisk.pl ([127.0.0.1]) by localhost (ogre.sisk.pl [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 26764-03; Sun, 29 Apr 2012 22:01:18 +0200 (CEST) Received: from ferrari.rjw.lan (62-121-64-87.home.aster.pl [62.121.64.87]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ogre.sisk.pl (Postfix) with ESMTP id 90FA11D4E1B; Sun, 29 Apr 2012 22:01:18 +0200 (CEST) From: "Rafael J. Wysocki" To: Bjorn Helgaas , Len Brown Subject: [PATCH] ACPI / PCI: Make _SxD/_SxW check follow ACPI 4.0a spec Date: Sun, 29 Apr 2012 22:44:16 +0200 User-Agent: KMail/1.13.6 (Linux/3.4.0-rc4+; KDE/4.6.0; x86_64; ; ) Cc: ACPI Devel Mailing List , Linux PM list , linux-pci@vger.kernel.org, Alan Stern , "Oleksij Rempel (fishor)" , LKML MIME-Version: 1.0 Message-Id: <201204292244.16467.rjw@sisk.pl> X-Virus-Scanned: amavisd-new at ogre.sisk.pl using MkS_Vir for Linux Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Oleksij Rempel This patch makes _SxD/_SxW check follow the ACPI 4.0a specification more closely and fixes suspend bug found on ASUS Zenbook UX31E. Some OEM use _SxD fileds do blacklist brocken Dx states. If _SxD/_SxW return values are check before suspend as appropriate, some nasty suspend/resume issues may be avoided. References: https://bugzilla.kernel.org/show_bug.cgi?id=42728 Signed-off-by: Oleksij Rempel Signed-off-by: Rafael J. Wysocki --- Bjorn, Len, This is -stable material and therefore v3.4 as well, IMO. Please let me know if one of you can take it or whether you want me to handle it all the way to Linus. Thanks, Rafael --- drivers/acpi/sleep.c | 22 +++++++++++++++++++++- drivers/pci/pci.c | 12 +++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux/drivers/acpi/sleep.c =================================================================== --- linux.orig/drivers/acpi/sleep.c +++ linux/drivers/acpi/sleep.c @@ -714,10 +714,30 @@ int acpi_pm_device_sleep_state(struct de * * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer * provided -- that's our fault recovery, we ignore retval. + * + * According to ACPI 4.0a (April 5, 2010), page 294, + * Table 7-7 S3 Action / Result Table, we need to evaluate _SxW in + * addition to _SxD if the device is configured for wakeup: + * Desired Action | _S3D | _PRW | _S3W | Resultant D-state + * Enter S3 | N/A | D/C | N/A | OSPM decides + * Enter S3, No Wake | 2 | D/C | D/C | Enter D2 or D3 + * Enter S3, Wake | 2 | 3 | N/A | Enter D2 + * Enter S3, Wake | 2 | 3 | 3 | Enter D2 or D3 + * Enter S3, Wake | N/A | 3 | 2 | Enter D0, D1 or D2 */ - if (acpi_target_sleep_state > ACPI_STATE_S0) + if (acpi_target_sleep_state > ACPI_STATE_S0) { + acpi_status status; + acpi_evaluate_integer(handle, acpi_method, NULL, &d_min); + if (device_may_wakeup(dev)) { + acpi_method[3] = 'W'; + status = acpi_evaluate_integer(handle, acpi_method, + NULL, &d_max); + if (ACPI_FAILURE(status)) + d_max = d_min; + } + } /* * If _PRW says we can wake up the system from the target sleep state, * the D-state returned by _SxD is sufficient for that (we assume a Index: linux/drivers/pci/pci.c =================================================================== --- linux.orig/drivers/pci/pci.c +++ linux/drivers/pci/pci.c @@ -1691,10 +1691,20 @@ pci_power_t pci_target_state(struct pci_ { pci_power_t target_state = PCI_D3hot; - if (platform_pci_power_manageable(dev)) { + /* + * According to ACPI 4.0a,7.2 Device Power Management Objects, device + * with wake capability should have _PRW or _PSW object and can have + * _SxD or _SxW object. + * It looks like some OEMs use this fields to avoid buggy Dx states + * of devices, so we need to check for _PRW or _PSW and see if _SxD or + * _SxW indicate to overwrite Dx. + */ + if (platform_pci_power_manageable(dev) + || platform_pci_can_wakeup(dev)) { /* * Call the platform to choose the target state of the device * and enable wake-up from this state if supported. + * (Check _SxD and _SxW) */ pci_power_t state = platform_pci_choose_state(dev);