PCI/MSI: Free legacy IRQ when enabling MSI/MSI-X

Once MSI/MSI-X is enabled by the device driver, a PCI device won't use
legacy IRQs again until MSI/MSI-X is disabled.

Call pcibios_free_irq() when enabling MSI/MSI-X and pcibios_alloc_irq()
when disabling MSI/MSI-X.  This allows arch code to manage resources
associated with the legacy IRQ.

[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>
This commit is contained in:
Jiang Liu 2015-07-30 14:00:08 -05:00 committed by Bjorn Helgaas
parent 811a4e6fce
commit 5f2269916b
1 changed files with 4 additions and 1 deletions

View File

@ -665,6 +665,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
pci_msi_set_enable(dev, 1); pci_msi_set_enable(dev, 1);
dev->msi_enabled = 1; dev->msi_enabled = 1;
pcibios_free_irq(dev);
dev->irq = entry->irq; dev->irq = entry->irq;
return 0; return 0;
} }
@ -792,9 +793,9 @@ static int msix_capability_init(struct pci_dev *dev,
/* Set MSI-X enabled bits and unmask the function */ /* Set MSI-X enabled bits and unmask the function */
pci_intx_for_msi(dev, 0); pci_intx_for_msi(dev, 0);
dev->msix_enabled = 1; dev->msix_enabled = 1;
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
pcibios_free_irq(dev);
return 0; return 0;
out_avail: out_avail:
@ -909,6 +910,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
/* Restore dev->irq to its default pin-assertion irq */ /* Restore dev->irq to its default pin-assertion irq */
dev->irq = desc->msi_attrib.default_irq; dev->irq = desc->msi_attrib.default_irq;
pcibios_alloc_irq(dev);
} }
void pci_disable_msi(struct pci_dev *dev) void pci_disable_msi(struct pci_dev *dev)
@ -1009,6 +1011,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
pci_intx_for_msi(dev, 1); pci_intx_for_msi(dev, 1);
dev->msix_enabled = 0; dev->msix_enabled = 0;
pcibios_alloc_irq(dev);
} }
void pci_disable_msix(struct pci_dev *dev) void pci_disable_msix(struct pci_dev *dev)