summaryrefslogtreecommitdiff
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-10-01 16:14:24 +0200
committerThomas Gleixner <tglx@linutronix.de>2015-10-01 16:14:24 +0200
commitbebcb8dab6bac53b6a61a896db03781d1992cadb (patch)
tree4793b0c2e913db8cf573ee52d568471603273af6 /drivers/pci/quirks.c
parent26c21dd9885a2d8a4f4d539917c4877ffd399286 (diff)
parentf1e0bb0ad473a32d1b7e6d285ae9f7e47710bb5e (diff)
Merge branch 'irq/for-arm' into irq/core
Bring in the change which we offered arm[64] folks to pull into their trees.
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6a30252cd79f..b03373fd05ca 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1907,11 +1907,27 @@ static void quirk_netmos(struct pci_dev *dev)
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos);
+/*
+ * Quirk non-zero PCI functions to route VPD access through function 0 for
+ * devices that share VPD resources between functions. The functions are
+ * expected to be identical devices.
+ */
static void quirk_f0_vpd_link(struct pci_dev *dev)
{
- if (!dev->multifunction || !PCI_FUNC(dev->devfn))
+ struct pci_dev *f0;
+
+ if (!PCI_FUNC(dev->devfn))
return;
- dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
+
+ f0 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+ if (!f0)
+ return;
+
+ if (f0->vpd && dev->class == f0->class &&
+ dev->vendor == f0->vendor && dev->device == f0->device)
+ dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
+
+ pci_dev_put(f0);
}
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link);