summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c24
-rw-r--r--drivers/pci/probe.c8
2 files changed, 30 insertions, 2 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 9f5ccbeb4fa..f4512feac12 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -35,6 +35,9 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev)
u16 reg16 = 0;
int pos;
+ if (dev->aer_firmware_first)
+ return -EIO;
+
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return -EIO;
@@ -60,6 +63,9 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev)
u16 reg16 = 0;
int pos;
+ if (dev->aer_firmware_first)
+ return -EIO;
+
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos)
return -EIO;
@@ -874,8 +880,22 @@ void aer_delete_rootport(struct aer_rpc *rpc)
*/
int aer_init(struct pcie_device *dev)
{
- if (aer_osc_setup(dev) && !forceload)
- return -ENXIO;
+ if (dev->port->aer_firmware_first) {
+ dev_printk(KERN_DEBUG, &dev->device,
+ "PCIe errors handled by platform firmware.\n");
+ goto out;
+ }
+
+ if (aer_osc_setup(dev))
+ goto out;
return 0;
+out:
+ if (forceload) {
+ dev_printk(KERN_DEBUG, &dev->device,
+ "aerdrv forceload requested.\n");
+ dev->port->aer_firmware_first = 0;
+ return 0;
+ }
+ return -ENXIO;
}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 9cefc54a012..118463befef 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -11,6 +11,7 @@
#include <linux/cpumask.h>
#include <linux/pci-aspm.h>
#include <linux/iommu.h>
+#include <acpi/acpi_hest.h>
#include <xen/xen.h>
#include "pci.h"
@@ -706,6 +707,12 @@ static void set_pcie_hotplug_bridge(struct pci_dev *pdev)
pdev->is_hotplug_bridge = 1;
}
+static void set_pci_aer_firmware_first(struct pci_dev *pdev)
+{
+ if (acpi_hest_firmware_first_pci(pdev))
+ pdev->aer_firmware_first = 1;
+}
+
#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
/**
@@ -734,6 +741,7 @@ int pci_setup_device(struct pci_dev *dev)
dev->multifunction = !!(hdr_type & 0x80);
dev->error_state = pci_channel_io_normal;
set_pcie_port_type(dev);
+ set_pci_aer_firmware_first(dev);
list_for_each_entry(slot, &dev->bus->slots, list)
if (PCI_SLOT(dev->devfn) == slot->number)