aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@linux.intel.com>2015-06-10 16:54:58 +0800
committerBjorn Helgaas <bhelgaas@google.com>2015-07-30 13:59:47 -0500
commit890e4847587fcff5eb0438e90992ad7d2a261f33 (patch)
treefef98a9dd0c0cf4c328f55996733b822690e9de0 /drivers/pci/pci-driver.c
parentLinux 4.2-rc2 (diff)
downloadlinux-dev-890e4847587fcff5eb0438e90992ad7d2a261f33.tar.xz
linux-dev-890e4847587fcff5eb0438e90992ad7d2a261f33.zip
PCI: Add pcibios_alloc_irq() and pcibios_free_irq()
Add pcibios_alloc_irq() and pcibios_free_irq(), which are called when binding/unbinding PCI device drivers. PCI arch code may implement these to manage IRQ resources for hotplugged devices. [bhelgaas: changelog] Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 3cb2210de553..52a880ca1768 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -388,18 +388,31 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
return error;
}
+int __weak pcibios_alloc_irq(struct pci_dev *dev)
+{
+ return 0;
+}
+
+void __weak pcibios_free_irq(struct pci_dev *dev)
+{
+}
+
static int pci_device_probe(struct device *dev)
{
- int error = 0;
- struct pci_driver *drv;
- struct pci_dev *pci_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)
+ return error;
- 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)
+ if (error) {
+ pcibios_free_irq(pci_dev);
pci_dev_put(pci_dev);
+ }
return error;
}
@@ -415,6 +428,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;
}