aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h3
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c34
-rw-r--r--drivers/pci/pcie/portdrv_acpi.c2
4 files changed, 39 insertions, 2 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index f409948e1a9b..2b2b6508efde 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -416,7 +416,7 @@ static void aer_error_resume(struct pci_dev *dev)
416 */ 416 */
417static int __init aer_service_init(void) 417static int __init aer_service_init(void)
418{ 418{
419 if (!pci_aer_available()) 419 if (!pci_aer_available() || aer_acpi_firmware_first())
420 return -ENXIO; 420 return -ENXIO;
421 return pcie_port_service_register(&aerdriver); 421 return pcie_port_service_register(&aerdriver);
422} 422}
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 80c11d131499..9656e3060412 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -132,6 +132,7 @@ static inline int aer_osc_setup(struct pcie_device *pciedev)
132 132
133#ifdef CONFIG_ACPI_APEI 133#ifdef CONFIG_ACPI_APEI
134extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); 134extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev);
135extern bool aer_acpi_firmware_first(void);
135#else 136#else
136static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) 137static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
137{ 138{
@@ -139,6 +140,8 @@ static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
139 return pci_dev->__aer_firmware_first; 140 return pci_dev->__aer_firmware_first;
140 return 0; 141 return 0;
141} 142}
143
144static inline bool aer_acpi_firmware_first(void) { return false; }
142#endif 145#endif
143 146
144static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev, 147static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev,
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index 2bb9b8972211..275bf158ffa7 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -93,4 +93,38 @@ int pcie_aer_get_firmware_first(struct pci_dev *dev)
93 aer_set_firmware_first(dev); 93 aer_set_firmware_first(dev);
94 return dev->__aer_firmware_first; 94 return dev->__aer_firmware_first;
95} 95}
96
97static bool aer_firmware_first;
98
99static int aer_hest_parse_aff(struct acpi_hest_header *hest_hdr, void *data)
100{
101 struct acpi_hest_aer_common *p;
102
103 if (aer_firmware_first)
104 return 0;
105
106 switch (hest_hdr->type) {
107 case ACPI_HEST_TYPE_AER_ROOT_PORT:
108 case ACPI_HEST_TYPE_AER_ENDPOINT:
109 case ACPI_HEST_TYPE_AER_BRIDGE:
110 p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
111 aer_firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
112 default:
113 return 0;
114 }
115}
116
117/**
118 * aer_acpi_firmware_first - Check if APEI should control AER.
119 */
120bool aer_acpi_firmware_first(void)
121{
122 static bool parsed = false;
123
124 if (!parsed) {
125 apei_hest_parse(aer_hest_parse_aff, NULL);
126 parsed = true;
127 }
128 return aer_firmware_first;
129}
96#endif 130#endif
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c
index b7c4cb1ccb23..5982b6a63b89 100644
--- a/drivers/pci/pcie/portdrv_acpi.c
+++ b/drivers/pci/pcie/portdrv_acpi.c
@@ -49,7 +49,7 @@ int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask)
49 | OSC_PCI_EXPRESS_PME_CONTROL; 49 | OSC_PCI_EXPRESS_PME_CONTROL;
50 50
51 if (pci_aer_available()) { 51 if (pci_aer_available()) {
52 if (pcie_aer_get_firmware_first(port)) 52 if (aer_acpi_firmware_first())
53 dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n"); 53 dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n");
54 else 54 else
55 flags |= OSC_PCI_EXPRESS_AER_CONTROL; 55 flags |= OSC_PCI_EXPRESS_AER_CONTROL;