diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 3cb2210de5530e3edffd3286df3a66f455f6b2ec..52a880ca1768362ec41399e8df11c3504a28a107 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; } diff --git a/include/linux/pci.h b/include/linux/pci.h index 8a0321a8fb595892c5e80910d5c914c89ded63de..b4832c92f23e67d8109902104d13270dccf3a1d6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1645,6 +1645,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;