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
|
even if the platform doesn't give the OS permission to
|
||||||
use them. This may cause conflicts if the platform
|
use them. This may cause conflicts if the platform
|
||||||
also tries to use these services.
|
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
|
compat Disable native PCIe services (PME, AER, DPC, PCIe
|
||||||
hotplug).
|
hotplug).
|
||||||
|
|
||||||
|
|
|
@ -291,7 +291,7 @@ static int dpc_probe(struct pcie_device *dev)
|
||||||
int status;
|
int status;
|
||||||
u16 ctl, cap;
|
u16 ctl, cap;
|
||||||
|
|
||||||
if (pcie_aer_get_firmware_first(pdev))
|
if (pcie_aer_get_firmware_first(pdev) && !pcie_ports_dpc_native)
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
|
||||||
dpc = devm_kzalloc(device, sizeof(*dpc), GFP_KERNEL);
|
dpc = devm_kzalloc(device, sizeof(*dpc), GFP_KERNEL);
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
#define PCIE_PORT_DEVICE_MAXSERVICES 5
|
#define PCIE_PORT_DEVICE_MAXSERVICES 5
|
||||||
|
|
||||||
|
extern bool pcie_ports_dpc_native;
|
||||||
|
|
||||||
#ifdef CONFIG_PCIEAER
|
#ifdef CONFIG_PCIEAER
|
||||||
int pcie_aer_init(void);
|
int pcie_aer_init(void);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -250,8 +250,13 @@ static int get_port_device_capability(struct pci_dev *dev)
|
||||||
pcie_pme_interrupt_enable(dev, false);
|
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) &&
|
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;
|
services |= PCIE_PORT_SERVICE_DPC;
|
||||||
|
|
||||||
if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||
|
if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||
|
||||||
|
|
|
@ -29,12 +29,20 @@ bool pcie_ports_disabled;
|
||||||
*/
|
*/
|
||||||
bool pcie_ports_native;
|
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)
|
static int __init pcie_port_setup(char *str)
|
||||||
{
|
{
|
||||||
if (!strncmp(str, "compat", 6))
|
if (!strncmp(str, "compat", 6))
|
||||||
pcie_ports_disabled = true;
|
pcie_ports_disabled = true;
|
||||||
else if (!strncmp(str, "native", 6))
|
else if (!strncmp(str, "native", 6))
|
||||||
pcie_ports_native = true;
|
pcie_ports_native = true;
|
||||||
|
else if (!strncmp(str, "dpc-native", 10))
|
||||||
|
pcie_ports_dpc_native = true;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue