From patchwork Thu Aug 22 20:22:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Helgaas X-Patchwork-Id: 2848395 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BEA8E9F271 for ; Thu, 22 Aug 2013 20:22:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 634672057E for ; Thu, 22 Aug 2013 20:22:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4CD8620535 for ; Thu, 22 Aug 2013 20:22:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754458Ab3HVUWQ (ORCPT ); Thu, 22 Aug 2013 16:22:16 -0400 Received: from mail-ob0-f173.google.com ([209.85.214.173]:60532 "EHLO mail-ob0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754268Ab3HVUWM (ORCPT ); Thu, 22 Aug 2013 16:22:12 -0400 Received: by mail-ob0-f173.google.com with SMTP id ta17so4531982obb.4 for ; Thu, 22 Aug 2013 13:22:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=6t/CoWn0z/ZLySEAPTyA0NqlJWvE3CWoVhJkBT5HP0c=; b=Q9Os1w20D221RvYLrImQsGt2EL07yKqo35PaIPlF5Yhx3BkxgiIYLksH1AFNTwO4TH 2H7m8ciRzkTDqV29ng9kD3Z2lxbDJuCnysh1pDnCtEVu6J7WgCeJWiw5Q/wRbgAFndt4 05zaHzBpOmDxjD9Aej/qcwsT+0Aug63k9Jrzn8F7GcJEr/qaD1ZvqXOpsAKq0PG4o1x4 93z6E2oUPpCf5ecHDPS+PlDyrNkXsON2B78u1I9GeME/MUvryyxO5PwvQkpPin/zc57w c1Q+l3NQTLTsGTBFnIqoajdDySBVpAQWUYrgA2rUxLr4n7kWqmKqrBnDRCX9kqJVOT19 FdbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-type:content-disposition:in-reply-to :user-agent; bh=6t/CoWn0z/ZLySEAPTyA0NqlJWvE3CWoVhJkBT5HP0c=; b=GNlClJBBW3bOTkPbuU+PJU1KoeSnLoKF9BKKh3QeCfxsCDAQeTHbLXAO79NHrbw2aw 1mX0TrNZiWARR4E7cfU6gCR1zM3SDtv98G38DALOki08pL/VuwrPXvM8Icbx7zkDMT1M qiwUGdUXhCBA4eTpxz4aE1jDavaQ038EVqDg1QgKsZHhkpR3OMo39q6nx2oCYV6t94Nn iXBp+toVvQ5aHyc5/aVVV36hh6ImilrnoBw8lZvrmezGTyIrL/zqDN0BQp5WSybbgBm/ EwjOHo/ZTtX3p2bCaKOYHaPmiwO/IZjecDSs8gjFzeeLbuD2u/6lixAqOwwsjFtiuwB3 6ORA== X-Gm-Message-State: ALoCoQm4N3TwTtEiJzw3q7L3cT6GybUisSyv3vAUCGugAW2wtRtQCUUUNdW/wK2118fjgkjG6a8PjabhxspdLt4yJXEhESq+yqDCeaXv+bQF4S7AYZtWgPjzXqgbQkPmLRy7UaOsZT8yeSAGv3S0IPVEXhl6oXGtDMqHM3H6A4A6i3PRx4ryGkMYx2XPp9tdCzYHujAeRG++I3cwNp1+DqIEJpblSzTSWQ== X-Received: by 10.50.66.136 with SMTP id f8mr6807201igt.57.1377202930133; Thu, 22 Aug 2013 13:22:10 -0700 (PDT) Received: from google.com ([172.29.122.86]) by mx.google.com with ESMTPSA id cl4sm1932538igc.1.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 22 Aug 2013 13:22:09 -0700 (PDT) Date: Thu, 22 Aug 2013 14:22:06 -0600 From: Bjorn Helgaas To: "Rafael J. Wysocki" Cc: Sebastian Ott , "linux-pci@vger.kernel.org" Subject: Re: [PATCH] PCI: add hibernation hooks Message-ID: <20130822202206.GA1200@google.com> References: <3503956.Yk8myngYqt@vostro.rjw.lan> <3498248.Me8u1JmYkr@vostro.rjw.lan> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <3498248.Me8u1JmYkr@vostro.rjw.lan> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Thu, Aug 22, 2013 at 12:06:43AM +0200, Rafael J. Wysocki wrote: > -> the prevailing convention for representing platform options like that > seems to be to use a pointer to an object containing callback pointers. This > is what we do for pci_platform_pm and for suspend_ops, hibernation_ops etc. > I think it is just more flexible, because it allows the pointer to be left > unset if there is an initialization error of some sort or a command line > option disabling something is set etc. Good points. I put merged the error checking into the original patch and put it in my pci/misc branch. Here's the result; let me know if anything needs to be tweaked. PCI: Add pcibios_pm_ops for optional arch-specific hibernate functionality From: Sebastian Ott Platforms may want to provide architecture-specific functionality when a PCI device is doing a hibernate transition. Add a weak symbol pcibios_pm_ops that architectures can override to do so. [bhelgaas: fold in return value checks from v2 patch] Signed-off-by: Sebastian Ott Signed-off-by: Bjorn Helgaas --- drivers/pci/pci-driver.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 4 ++++ 2 files changed, 47 insertions(+) -- 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 diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e6515e2..98f7b9b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -763,6 +763,13 @@ static int pci_pm_resume(struct device *dev) #ifdef CONFIG_HIBERNATE_CALLBACKS + +/* + * pcibios_pm_ops - provide arch-specific hooks when a PCI device is doing + * a hibernate transition + */ +struct dev_pm_ops __weak pcibios_pm_ops; + static int pci_pm_freeze(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); @@ -786,6 +793,9 @@ static int pci_pm_freeze(struct device *dev) return error; } + if (pcibios_pm_ops.freeze) + return pcibios_pm_ops.freeze(dev); + return 0; } @@ -811,6 +821,9 @@ static int pci_pm_freeze_noirq(struct device *dev) pci_pm_set_unknown_state(pci_dev); + if (pcibios_pm_ops.freeze_noirq) + return pcibios_pm_ops.freeze_noirq(dev); + return 0; } @@ -820,6 +833,12 @@ static int pci_pm_thaw_noirq(struct device *dev) struct device_driver *drv = dev->driver; int error = 0; + if (pcibios_pm_ops.thaw_noirq) { + error = pcibios_pm_ops.thaw_noirq(dev); + if (error) + return error; + } + if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume_early(dev); @@ -837,6 +856,12 @@ static int pci_pm_thaw(struct device *dev) const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; int error = 0; + if (pcibios_pm_ops.thaw) { + error = pcibios_pm_ops.thaw(dev); + if (error) + return error; + } + if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume(dev); @@ -878,6 +903,9 @@ static int pci_pm_poweroff(struct device *dev) Fixup: pci_fixup_device(pci_fixup_suspend, pci_dev); + if (pcibios_pm_ops.poweroff) + return pcibios_pm_ops.poweroff(dev); + return 0; } @@ -911,6 +939,9 @@ static int pci_pm_poweroff_noirq(struct device *dev) if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) pci_write_config_word(pci_dev, PCI_COMMAND, 0); + if (pcibios_pm_ops.poweroff_noirq) + return pcibios_pm_ops.poweroff_noirq(dev); + return 0; } @@ -920,6 +951,12 @@ static int pci_pm_restore_noirq(struct device *dev) struct device_driver *drv = dev->driver; int error = 0; + if (pcibios_pm_ops.restore_noirq) { + error = pcibios_pm_ops.restore_noirq(dev); + if (error) + return error; + } + pci_pm_default_resume_early(pci_dev); if (pci_has_legacy_pm_support(pci_dev)) @@ -937,6 +974,12 @@ static int pci_pm_restore(struct device *dev) const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; int error = 0; + if (pcibios_pm_ops.restore) { + error = pcibios_pm_ops.restore(dev); + if (error) + return error; + } + /* * This is necessary for the hibernation error path in which restore is * called without restoring the standard config registers of the device. diff --git a/include/linux/pci.h b/include/linux/pci.h index 0fd1f15..89ed123 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1648,6 +1648,10 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, int pcibios_add_device(struct pci_dev *dev); void pcibios_release_device(struct pci_dev *dev); +#ifdef CONFIG_HIBERNATE_CALLBACKS +extern struct dev_pm_ops pcibios_pm_ops; +#endif + #ifdef CONFIG_PCI_MMCONFIG void __init pci_mmcfg_early_init(void); void __init pci_mmcfg_late_init(void);