summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2016-07-12 12:20:17 +0300
committerBjorn Helgaas <bhelgaas@google.com>2016-07-21 23:50:07 +0300
commitaff171641d181ea573380efc3f559c9de4741fc5 (patch)
tree4db964cfabf120e9e9f1cba6f8d1707ae5bc8159 /include
parent3ac020e0ca8beff9b695f9866a06d50c09c602d6 (diff)
downloadlinux-aff171641d181ea573380efc3f559c9de4741fc5.tar.xz
PCI: Provide sensible IRQ vector alloc/free routines
Add a function to allocate and free a range of interrupt vectors, using MSI-X, MSI or legacy vectors (in that order) based on the capabilities of the underlying device and PCIe complex. Additionally a new helper is provided to get the Linux IRQ number for given device-relative vector so that the drivers don't need to allocate their own arrays to keep track of the vectors for the multi vector MSI-X case. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Alexander Gordeev <agordeev@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/pci.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b67e4df20801..52ecd49e8049 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1237,6 +1237,10 @@ resource_size_t pcibios_iov_resource_alignment(struct pci_dev *dev, int resno);
int pci_set_vga_state(struct pci_dev *pdev, bool decode,
unsigned int command_bits, u32 flags);
+#define PCI_IRQ_NOLEGACY (1 << 0) /* don't use legacy interrupts */
+#define PCI_IRQ_NOMSI (1 << 1) /* don't use MSI interrupts */
+#define PCI_IRQ_NOMSIX (1 << 2) /* don't use MSI-X interrupts */
+
/* kmem_cache style wrapper around pci_alloc_consistent() */
#include <linux/pci-dma.h>
@@ -1284,6 +1288,11 @@ static inline int pci_enable_msix_exact(struct pci_dev *dev,
return rc;
return 0;
}
+int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
+ unsigned int max_vecs, unsigned int flags);
+void pci_free_irq_vectors(struct pci_dev *dev);
+int pci_irq_vector(struct pci_dev *dev, unsigned int nr);
+
#else
static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; }
static inline void pci_msi_shutdown(struct pci_dev *dev) { }
@@ -1307,6 +1316,24 @@ static inline int pci_enable_msix_range(struct pci_dev *dev,
static inline int pci_enable_msix_exact(struct pci_dev *dev,
struct msix_entry *entries, int nvec)
{ return -ENOSYS; }
+static inline int pci_alloc_irq_vectors(struct pci_dev *dev,
+ unsigned int min_vecs, unsigned int max_vecs,
+ unsigned int flags)
+{
+ if (min_vecs > 1)
+ return -EINVAL;
+ return 1;
+}
+static inline void pci_free_irq_vectors(struct pci_dev *dev)
+{
+}
+
+static inline int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
+{
+ if (WARN_ON_ONCE(nr > 0))
+ return -EINVAL;
+ return dev->irq;
+}
#endif
#ifdef CONFIG_PCIEPORTBUS