From patchwork Wed Aug 31 06:15:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 9306361 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9172160865 for ; Wed, 31 Aug 2016 06:15:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7EC3C28E26 for ; Wed, 31 Aug 2016 06:15:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 737D628E32; Wed, 31 Aug 2016 06:15:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4277828E28 for ; Wed, 31 Aug 2016 06:15:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758917AbcHaGPj (ORCPT ); Wed, 31 Aug 2016 02:15:39 -0400 Received: from mailout1.hostsharing.net ([83.223.95.204]:58723 "EHLO mailout1.hostsharing.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758588AbcHaGPh (ORCPT ); Wed, 31 Aug 2016 02:15:37 -0400 Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mailout1.hostsharing.net (Postfix) with ESMTPS id 728FD101BB5EE; Wed, 31 Aug 2016 08:15:28 +0200 (CEST) Received: from localhost (4-38-90-81.adsl.cmo.de [81.90.38.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 3E309600B438; Wed, 31 Aug 2016 08:15:27 +0200 (CEST) X-Mailbox-Line: From 885bb1c3a5cebbc2c22e1f77426d54cde2a4867c Mon Sep 17 00:00:00 2001 Message-Id: <885bb1c3a5cebbc2c22e1f77426d54cde2a4867c.1472554278.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Wed, 31 Aug 2016 08:15:18 +0200 Subject: [PATCH 1/4] PCI: Afford direct-complete to devices with nonstandard PM To: linux-pci@vger.kernel.org Cc: linux-pm@vger.kernel.org, linux-acpi@vger.kernel.org, "Rafael J. Wysocki" , Peter Wu , Andreas Noever Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There are devices not power-manageable by the platform, but still able to runtime suspend to D3cold with a nonstandard mechanism. One example is laptop hybrid graphics where the discrete GPU and its built-in HDA controller are power-managed either with a _DSM (AMD PowerXpress, Nvidia Optimus) or a separate gmux controller (MacBook Pro). Another example is Thunderbolt on Macs which is power-managed with custom ACPI methods. When putting the system to sleep, we currently handle such devices improperly by transitioning them from D3cold to D3hot (the default power state defined at the top of pci_target_state()). This wastes energy and prolongs the suspend sequence (powering up the Thunderbolt controller takes 2 seconds). Avoid that by assuming that a nonstandard PM mechanism is at work if the device is not platform-power-manageable but currently in D3cold. If the device is wakeup enabled, we might still have to wake it up from D3cold if PME cannot be signaled from that power state. The check for devices without PM capability comes before the check for D3cold since such devices could in theory also be powered down by nonstandard means and should then be afforded direct-complete as well. Cc: Rafael J. Wysocki Signed-off-by: Lukas Wunner Acked-by: Rafael J. Wysocki --- drivers/pci/pci.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index aab9d51..72a9d3a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1959,9 +1959,22 @@ static pci_power_t pci_target_state(struct pci_dev *dev) default: target_state = state; } - } else if (!dev->pm_cap) { + + return target_state; + } + + if (!dev->pm_cap) target_state = PCI_D0; - } else if (device_may_wakeup(&dev->dev)) { + + /* + * If the device is in D3cold even though it's not power-manageable by + * the platform, it may have been powered down by nonstandard means. + * Best to let it slumber. + */ + if (dev->current_state == PCI_D3cold) + target_state = PCI_D3cold; + + if (device_may_wakeup(&dev->dev)) { /* * Find the deepest state from which the device can generate * wake-up events, make it the target state and enable device