PCI/DPC: Add "pcie_ports=dpc-native" to allow DPC without AER control
Prior toeed85ff4c0
("PCI/DPC: Enable DPC only if AER is available"), Linux handled DPC events regardless of whether firmware had granted it ownership of AER or DPC, e.g., via _OSC. PCIe r5.0, sec 6.2.10, recommends that the OS link control of DPC to control of AER, so aftereed85ff4c0
, Linux handles DPC events only if it has control of AER. On platforms that do not grant OS control of AER via _OSC, Linux DPC handling worked beforeeed85ff4c0
but not after. To make Linux DPC handling work on those platforms the same way they did before, add a "pcie_ports=dpc-native" kernel parameter that makes Linux handle DPC events regardless of whether it has control of AER. [bhelgaas: commit log, move pcie_ports_dpc_native to drivers/pci/] Link: https://lore.kernel.org/r/20191023192205.97024-1-olof@lixom.net Signed-off-by: Olof Johansson <olof@lixom.net> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
161eea1b25
commit
35a0b2378c
|
@ -3540,6 +3540,8 @@
|
|||
even if the platform doesn't give the OS permission to
|
||||
use them. This may cause conflicts if the platform
|
||||
also tries to use these services.
|
||||
dpc-native Use native PCIe service for DPC only. May
|
||||
cause conflicts if firmware uses AER or DPC.
|
||||
compat Disable native PCIe services (PME, AER, DPC, PCIe
|
||||
hotplug).
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ static int dpc_probe(struct pcie_device *dev)
|
|||
int status;
|
||||
u16 ctl, cap;
|
||||
|
||||
if (pcie_aer_get_firmware_first(pdev))
|
||||
if (pcie_aer_get_firmware_first(pdev) && !pcie_ports_dpc_native)
|
||||
return -ENOTSUPP;
|
||||
|
||||
dpc = devm_kzalloc(device, sizeof(*dpc), GFP_KERNEL);
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#define PCIE_PORT_DEVICE_MAXSERVICES 5
|
||||
|
||||
extern bool pcie_ports_dpc_native;
|
||||
|
||||
#ifdef CONFIG_PCIEAER
|
||||
int pcie_aer_init(void);
|
||||
#else
|
||||
|
|
|
@ -250,8 +250,13 @@ static int get_port_device_capability(struct pci_dev *dev)
|
|||
pcie_pme_interrupt_enable(dev, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* With dpc-native, allow Linux to use DPC even if it doesn't have
|
||||
* permission to use AER.
|
||||
*/
|
||||
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC) &&
|
||||
pci_aer_available() && services & PCIE_PORT_SERVICE_AER)
|
||||
pci_aer_available() &&
|
||||
(pcie_ports_dpc_native || (services & PCIE_PORT_SERVICE_AER)))
|
||||
services |= PCIE_PORT_SERVICE_DPC;
|
||||
|
||||
if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||
|
||||
|
|
|
@ -29,12 +29,20 @@ bool pcie_ports_disabled;
|
|||
*/
|
||||
bool pcie_ports_native;
|
||||
|
||||
/*
|
||||
* If the user specified "pcie_ports=dpc-native", use the Linux DPC PCIe
|
||||
* service even if the platform hasn't given us permission.
|
||||
*/
|
||||
bool pcie_ports_dpc_native;
|
||||
|
||||
static int __init pcie_port_setup(char *str)
|
||||
{
|
||||
if (!strncmp(str, "compat", 6))
|
||||
pcie_ports_disabled = true;
|
||||
else if (!strncmp(str, "native", 6))
|
||||
pcie_ports_native = true;
|
||||
else if (!strncmp(str, "dpc-native", 10))
|
||||
pcie_ports_dpc_native = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue