1 // SPDX-License-Identifier: GPL-2.0
3 * PCI Message Signaled Interrupt (MSI).
5 * Legacy architecture specific setup and teardown mechanism.
10 int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
15 void __weak arch_teardown_msi_irq(unsigned int irq)
19 int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
21 struct msi_desc *desc;
25 * If an architecture wants to support multiple MSI, it needs to
26 * override arch_setup_msi_irqs()
28 if (type == PCI_CAP_ID_MSI && nvec > 1)
31 for_each_pci_msi_entry(desc, dev) {
32 ret = arch_setup_msi_irq(dev, desc);
34 return ret < 0 ? ret : -ENOSPC;
40 void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
42 struct msi_desc *desc;
45 for_each_pci_msi_entry(desc, dev) {
47 for (i = 0; i < desc->nvec_used; i++)
48 arch_teardown_msi_irq(desc->irq + i);
53 static int pci_msi_setup_check_result(struct pci_dev *dev, int type, int ret)
55 struct msi_desc *entry;
58 if (type != PCI_CAP_ID_MSIX || ret >= 0)
61 /* Scan the MSI descriptors for successfully allocated ones. */
62 for_each_pci_msi_entry(entry, dev) {
66 return avail ? avail : ret;
69 int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
71 int ret = arch_setup_msi_irqs(dev, nvec, type);
73 ret = pci_msi_setup_check_result(dev, type, ret);
75 ret = msi_device_populate_sysfs(&dev->dev);
79 void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev)
81 msi_device_destroy_sysfs(&dev->dev);
82 arch_teardown_msi_irqs(dev);
83 msi_free_msi_descs(&dev->dev);