From patchwork Sun Feb 18 08:38:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 10226675 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 61BB76055B for ; Sun, 18 Feb 2018 08:39:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4FC8A28868 for ; Sun, 18 Feb 2018 08:39:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 437D12899F; Sun, 18 Feb 2018 08:39:16 +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=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6FA5A289F0 for ; Sun, 18 Feb 2018 08:39:15 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 35B76267219; Sun, 18 Feb 2018 09:39:14 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 3C7D926721A; Sun, 18 Feb 2018 09:39:13 +0100 (CET) Received: from mailout3.hostsharing.net (mailout3.hostsharing.net [176.9.242.54]) by alsa0.perex.cz (Postfix) with ESMTP id 58F052671A3 for ; Sun, 18 Feb 2018 09:39:10 +0100 (CET) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.hostsharing.net", Issuer "COMODO RSA Domain Validation Secure Server CA" (not verified)) by mailout3.hostsharing.net (Postfix) with ESMTPS id 0EE62104CF307; Sun, 18 Feb 2018 09:39:10 +0100 (CET) Received: from localhost (6-38-90-81.adsl.cmo.de [81.90.38.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 00CE6603E059; Sun, 18 Feb 2018 09:39:08 +0100 (CET) X-Mailbox-Line: From f7593132608eb9a83d7268cc5b3ef12b3dd9c52d Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Lukas Wunner Date: Sun, 18 Feb 2018 09:38:32 +0100 To: dri-devel@lists.freedesktop.org Cc: Pierre Moreau , alsa-devel@alsa-project.org, Lyude Paul , linux-pm@vger.kernel.org, nouveau@lists.freedesktop.org, "Rafael J. Wysocki" , Takashi Iwai , Hans de Goede , Peter Wu , Bastien Nocera , linux-pci@vger.kernel.org, Alex Deucher , Dave Airlie , Bjorn Helgaas , Ben Skeggs Subject: [alsa-devel] [PATCH 1/7] PCI: Restore BARs on runtime resume despite being unbound X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP PCI devices not bound to a driver are supposed to stay in D0 during runtime suspend. But they may have a parent which is bound and can be transitioned to D3cold at runtime. Once the parent goes to D3cold, the unbound child may go to D3cold as well. When the child comes out of D3cold, its BARs are uninitialized and thus inaccessible when a driver tries to probe. One example are recent hybrid graphics laptops which cut power to the discrete GPU when the root port above it goes to ACPI power state D3. Users may provoke this by unbinding the GPU driver and allowing runtime PM on the GPU via sysfs: The PM core will then treat the GPU as "suspended", which in turn allows the root port to runtime suspend, causing the power resources listed in its _PR3 object to be powered off. The GPU's BARs will be uninitialized when a driver later probes it. Another example are hybrid graphics laptops where the GPU itself (rather than the root port) is capable of runtime suspending to D3cold. If the GPU's integrated HDA controller is not bound and the GPU's driver decides to runtime suspend to D3cold, the HDA controller's BARs will be uninitialized when a driver later probes it. Fix by restoring the BARs on runtime resume if the device is not bound. This is sufficient to fix the above-mentioned use cases. Other use cases might require a full-blown pci_save_state() / pci_restore_state() or execution of fixups. We can add that once use cases materialize, let's not inflate the code unnecessarily. Cc: Bjorn Helgaas Cc: Rafael J. Wysocki Signed-off-by: Lukas Wunner Reviewed-by: Rafael J. Wysocki --- drivers/pci/pci-driver.c | 8 ++++++-- drivers/pci/pci.c | 2 +- drivers/pci/pci.h | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 3bed6beda051..51b11cbd48f6 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1277,10 +1277,14 @@ static int pci_pm_runtime_resume(struct device *dev) /* * If pci_dev->driver is not set (unbound), the device should - * always remain in D0 regardless of the runtime PM status + * always remain in D0 regardless of the runtime PM status. + * But if its parent can go to D3cold, this device may have + * been in D3cold as well and require restoration of its BARs. */ - if (!pci_dev->driver) + if (!pci_dev->driver) { + pci_restore_bars(pci_dev); return 0; + } if (!pm || !pm->runtime_resume) return -ENOSYS; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f6a4dd10d9b0..f694650235f2 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -563,7 +563,7 @@ int pci_wait_for_pending(struct pci_dev *dev, int pos, u16 mask) * Restore the BAR values for a given device, so as to make it * accessible by its driver. */ -static void pci_restore_bars(struct pci_dev *dev) +void pci_restore_bars(struct pci_dev *dev) { int i; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index fcd81911b127..29dc15bbe3bf 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -83,6 +83,7 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev); void pci_free_cap_save_buffers(struct pci_dev *dev); bool pci_bridge_d3_possible(struct pci_dev *dev); void pci_bridge_d3_update(struct pci_dev *dev); +void pci_restore_bars(struct pci_dev *dev); static inline void pci_wakeup_event(struct pci_dev *dev) {