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 msi_for_each_desc(desc
, &dev
->dev
, MSI_DESC_NOTASSOCIATED
) {
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 msi_for_each_desc(desc
, &dev
->dev
, MSI_DESC_ASSOCIATED
) {
46 for (i
= 0; i
< desc
->nvec_used
; i
++)
47 arch_teardown_msi_irq(desc
->irq
+ i
);
51 static int pci_msi_setup_check_result(struct pci_dev
*dev
, int type
, int ret
)
53 struct msi_desc
*desc
;
56 if (type
!= PCI_CAP_ID_MSIX
|| ret
>= 0)
59 /* Scan the MSI descriptors for successfully allocated ones. */
60 msi_for_each_desc(desc
, &dev
->dev
, MSI_DESC_ASSOCIATED
)
63 return avail
? avail
: ret
;
66 int pci_msi_legacy_setup_msi_irqs(struct pci_dev
*dev
, int nvec
, int type
)
68 int ret
= arch_setup_msi_irqs(dev
, nvec
, type
);
70 ret
= pci_msi_setup_check_result(dev
, type
, ret
);
72 ret
= msi_device_populate_sysfs(&dev
->dev
);
76 void pci_msi_legacy_teardown_msi_irqs(struct pci_dev
*dev
)
78 msi_device_destroy_sysfs(&dev
->dev
);
79 arch_teardown_msi_irqs(dev
);