From patchwork Thu May 7 03:12:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiang Liu X-Patchwork-Id: 6353461 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B8D1FBEEE1 for ; Thu, 7 May 2015 03:11:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D5C8A20396 for ; Thu, 7 May 2015 03:11:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3892F203AA for ; Thu, 7 May 2015 03:11:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751573AbbEGDLy (ORCPT ); Wed, 6 May 2015 23:11:54 -0400 Received: from mga02.intel.com ([134.134.136.20]:26433 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751294AbbEGDKr (ORCPT ); Wed, 6 May 2015 23:10:47 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 06 May 2015 20:10:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,382,1427785200"; d="scan'208";a="706463703" Received: from gerry-dev.bj.intel.com ([10.238.158.61]) by fmsmga001.fm.intel.com with ESMTP; 06 May 2015 20:10:44 -0700 From: Jiang Liu To: Thomas Gleixner , "Rafael J . Wysocki" , Bjorn Helgaas Cc: Jiang Liu , Lv Zheng , LKML , linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org, "x86 @ kernel . org" Subject: [RFC 1/4] PCI: Add hooks to allocate/free IRQ resources when binding/unbinding driver Date: Thu, 7 May 2015 11:12:51 +0800 Message-Id: <1430968374-29286-2-git-send-email-jiang.liu@linux.intel.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1430968374-29286-1-git-send-email-jiang.liu@linux.intel.com> References: <1430968374-29286-1-git-send-email-jiang.liu@linux.intel.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 Add two hook points pcibios_{alloc|free}_irq() into PCI core, which will be called when binding/unbinding PCI device drivers. Then PCI arch code may hook into these two points to allocate IRQ resources on demand and free them when not used anymore. Signed-off-by: Jiang Liu --- drivers/pci/pci-driver.c | 33 +++++++++++++++++++++++---------- include/linux/pci.h | 2 ++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 3cb2210de553..8af4a671686f 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -388,18 +388,30 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) return error; } -static int pci_device_probe(struct device *dev) +int __weak pcibios_alloc_irq(struct pci_dev *dev) { - int error = 0; - struct pci_driver *drv; - struct pci_dev *pci_dev; + return dev->irq; +} - drv = to_pci_driver(dev->driver); - pci_dev = to_pci_dev(dev); - pci_dev_get(pci_dev); - error = __pci_device_probe(drv, pci_dev); - if (error) - pci_dev_put(pci_dev); +void __weak pcibios_free_irq(struct pci_dev *dev) +{ +} + +static int pci_device_probe(struct device *dev) +{ + int error; + struct pci_dev *pci_dev = to_pci_dev(dev); + struct pci_driver *drv = to_pci_driver(dev->driver); + + error = pcibios_alloc_irq(pci_dev); + if (error >= 0) { + pci_dev_get(pci_dev); + error = __pci_device_probe(drv, pci_dev); + if (error) { + pcibios_free_irq(pci_dev); + pci_dev_put(pci_dev); + } + } return error; } @@ -415,6 +427,7 @@ static int pci_device_remove(struct device *dev) drv->remove(pci_dev); pm_runtime_put_noidle(dev); } + pcibios_free_irq(pci_dev); pci_dev->driver = NULL; } diff --git a/include/linux/pci.h b/include/linux/pci.h index 353db8dc4c6e..f50d16a04abc 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1656,6 +1656,8 @@ 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); void pcibios_penalize_isa_irq(int irq, int active); +int pcibios_alloc_irq(struct pci_dev *dev); +void pcibios_free_irq(struct pci_dev *dev); #ifdef CONFIG_HIBERNATE_CALLBACKS extern struct dev_pm_ops pcibios_pm_ops;