From patchwork Thu Sep 13 14:33:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 10599651 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BF16715A7 for ; Thu, 13 Sep 2018 14:33:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF4A62942D for ; Thu, 13 Sep 2018 14:33:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A3B9B2B067; Thu, 13 Sep 2018 14:33:34 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable 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 43B122A471 for ; Thu, 13 Sep 2018 14:33:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728121AbeIMTnU (ORCPT ); Thu, 13 Sep 2018 15:43:20 -0400 Received: from mga04.intel.com ([192.55.52.120]:17488 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728118AbeIMTnU (ORCPT ); Thu, 13 Sep 2018 15:43:20 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Sep 2018 07:33:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,369,1531810800"; d="scan'208";a="80171670" Received: from black.fi.intel.com ([10.237.72.28]) by FMSMGA003.fm.intel.com with ESMTP; 13 Sep 2018 07:33:27 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id C85B72A9; Thu, 13 Sep 2018 17:33:22 +0300 (EEST) From: Mika Westerberg To: Bjorn Helgaas , "Rafael J. Wysocki" Cc: Len Brown , Lukas Wunner , Keith Busch , Ashok Raj , Mario.Limonciello@dell.com, Anthony Wong , Linus Walleij , Sakari Ailus , Mika Westerberg , linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org Subject: [PATCH v2 06/10] PCI: portdrv: Add runtime PM hooks for port service drivers Date: Thu, 13 Sep 2018 17:33:18 +0300 Message-Id: <20180913143322.77953-7-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180913143322.77953-1-mika.westerberg@linux.intel.com> References: <20180913143322.77953-1-mika.westerberg@linux.intel.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When PCIe port is runtime suspended/resumed some extra steps might be needed to be executed from the port service driver side. For instance we may need to disable PCIe hotplug interrupt to prevent it from triggering immediately when PCIe link to the downstream component goes down. To make the above possible add optional ->runtime_suspend() and ->runtime_resume() callbacks to struct pcie_port_service_driver and call them for each port service in runtime suspend/resume callbacks of portdrv. Signed-off-by: Mika Westerberg Reviewed-by: Rafael J. Wysocki --- drivers/pci/pcie/portdrv.h | 4 ++++ drivers/pci/pcie/portdrv_core.c | 20 ++++++++++++++++++++ drivers/pci/pcie/portdrv_pci.c | 10 ++++------ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index d59afa42fc14..72fa132060e5 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -52,6 +52,8 @@ struct pcie_port_service_driver { int (*suspend) (struct pcie_device *dev); int (*resume_noirq) (struct pcie_device *dev); int (*resume) (struct pcie_device *dev); + int (*runtime_suspend) (struct pcie_device *dev); + int (*runtime_resume) (struct pcie_device *dev); /* Device driver may resume normal operations */ void (*error_resume)(struct pci_dev *dev); @@ -85,6 +87,8 @@ int pcie_port_device_register(struct pci_dev *dev); int pcie_port_device_suspend(struct device *dev); int pcie_port_device_resume_noirq(struct device *dev); int pcie_port_device_resume(struct device *dev); +int pcie_port_device_runtime_suspend(struct device *dev); +int pcie_port_device_runtime_resume(struct device *dev); #endif void pcie_port_device_remove(struct pci_dev *dev); int __must_check pcie_port_bus_register(void); diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 7c37d815229e..6542c48c7f59 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -395,6 +395,26 @@ int pcie_port_device_resume(struct device *dev) size_t off = offsetof(struct pcie_port_service_driver, resume); return device_for_each_child(dev, &off, pm_iter); } + +/** + * pcie_port_device_runtime_suspend - runtime suspend port services + * @dev: PCI Express port to handle + */ +int pcie_port_device_runtime_suspend(struct device *dev) +{ + size_t off = offsetof(struct pcie_port_service_driver, runtime_suspend); + return device_for_each_child(dev, &off, pm_iter); +} + +/** + * pcie_port_device_runtime_resume - runtime resume port services + * @dev: PCI Express port to handle + */ +int pcie_port_device_runtime_resume(struct device *dev) +{ + size_t off = offsetof(struct pcie_port_service_driver, runtime_resume); + return device_for_each_child(dev, &off, pm_iter); +} #endif /* PM */ static int remove_iter(struct device *dev, void *data) diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 629d5fe4c9b5..42d72cab3b1d 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -45,12 +45,10 @@ __setup("pcie_ports=", pcie_port_setup); #ifdef CONFIG_PM static int pcie_port_runtime_suspend(struct device *dev) { - return to_pci_dev(dev)->bridge_d3 ? 0 : -EBUSY; -} + if (!to_pci_dev(dev)->bridge_d3) + return -EBUSY; -static int pcie_port_runtime_resume(struct device *dev) -{ - return 0; + return pcie_port_device_runtime_suspend(dev); } static int pcie_port_runtime_idle(struct device *dev) @@ -73,7 +71,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { .restore_noirq = pcie_port_device_resume_noirq, .restore = pcie_port_device_resume, .runtime_suspend = pcie_port_runtime_suspend, - .runtime_resume = pcie_port_runtime_resume, + .runtime_resume = pcie_port_device_runtime_resume, .runtime_idle = pcie_port_runtime_idle, };