PCI: add pci_swizzle_interrupt_pin()
[firefly-linux-kernel-4.4.55.git] / drivers / pci / pci.c
index bd52ca4c28933804dda155941c13e4c01f99095d..d4d71fae623352143a5691e72c25871bc6684818 100644 (file)
@@ -1366,6 +1366,20 @@ void pci_enable_ari(struct pci_dev *dev)
        bridge->ari_enabled = 1;
 }
 
+/**
+ * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
+ * @dev: the PCI device
+ * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD)
+ *
+ * Perform INTx swizzling for a device behind one level of bridge.  This is
+ * required by section 9.1 of the PCI-to-PCI bridge specification for devices
+ * behind bridges on add-in cards.
+ */
+u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin)
+{
+       return (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+}
+
 int
 pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
 {
@@ -1376,7 +1390,7 @@ pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
                return -1;
 
        while (dev->bus->self) {
-               pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+               pin = pci_swizzle_interrupt_pin(dev, pin);
                dev = dev->bus->self;
        }
        *bridge = dev;