mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Merge branch 'pci/portdrv'
- Assume control of portdrv-related features only when portdrv is enabled, since we can't use them without portdrv (Kuppuswamy Sathyanarayanan) - Tidy _OSC control bit checking (Kuppuswamy Sathyanarayanan) - Centralize feature ownership checking so code only needs to check 'host->native_X' and doesn't need to also check 'pcie_ports_native' (Kuppuswamy Sathyanarayanan) * pci/portdrv: PCI/ACPI: Centralize pcie_ports_native checking PCI/ACPI: Tidy _OSC control bit checking PCI: Assume control of portdrv-related features only when portdrv enabled
This commit is contained in:
commit
3b5bba12f5
|
|
@ -993,6 +993,25 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
|
|||
__acpi_pci_root_release_info(bridge->release_data);
|
||||
}
|
||||
|
||||
#define OSC_OWNER(ctrl, bit, flag) \
|
||||
do { \
|
||||
if (!((ctrl) & (bit))) \
|
||||
flag = 0; \
|
||||
} while (0)
|
||||
|
||||
#define FLAG(x) ((x) ? '+' : '-')
|
||||
|
||||
/*
|
||||
* _OSC control bits for the features implemented by the PCIe port driver,
|
||||
* i.e., the ones "pcie_ports=native" applies to. LTR and SHPC hotplug are
|
||||
* negotiated via _OSC as well, but they are not portdrv services, so
|
||||
* "pcie_ports=" has no bearing on them.
|
||||
*/
|
||||
#define OSC_PCIE_PORT_SERVICE_CONTROLS (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \
|
||||
OSC_PCI_EXPRESS_PME_CONTROL | \
|
||||
OSC_PCI_EXPRESS_AER_CONTROL | \
|
||||
OSC_PCI_EXPRESS_DPC_CONTROL)
|
||||
|
||||
struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
|
||||
struct acpi_pci_root_ops *ops,
|
||||
struct acpi_pci_root_info *info,
|
||||
|
|
@ -1003,6 +1022,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
|
|||
int node = acpi_get_node(device->handle);
|
||||
struct pci_bus *bus;
|
||||
struct pci_host_bridge *host_bridge;
|
||||
u32 ctrl, ext_ctrl, override = 0;
|
||||
|
||||
info->root = root;
|
||||
info->bridge = device;
|
||||
|
|
@ -1028,21 +1048,49 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
|
|||
goto out_release_info;
|
||||
|
||||
host_bridge = to_pci_host_bridge(bus->bridge);
|
||||
if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
|
||||
host_bridge->native_pcie_hotplug = 0;
|
||||
if (!(root->osc_control_set & OSC_PCI_SHPC_NATIVE_HP_CONTROL))
|
||||
host_bridge->native_shpc_hotplug = 0;
|
||||
if (!(root->osc_control_set & OSC_PCI_EXPRESS_AER_CONTROL))
|
||||
host_bridge->native_aer = 0;
|
||||
if (!(root->osc_control_set & OSC_PCI_EXPRESS_PME_CONTROL))
|
||||
host_bridge->native_pme = 0;
|
||||
if (!(root->osc_control_set & OSC_PCI_EXPRESS_LTR_CONTROL))
|
||||
host_bridge->native_ltr = 0;
|
||||
if (!(root->osc_control_set & OSC_PCI_EXPRESS_DPC_CONTROL))
|
||||
host_bridge->native_dpc = 0;
|
||||
|
||||
if (!(root->osc_ext_control_set & OSC_CXL_ERROR_REPORTING_CONTROL))
|
||||
host_bridge->native_cxl_error = 0;
|
||||
ctrl = root->osc_control_set;
|
||||
ext_ctrl = root->osc_ext_control_set;
|
||||
|
||||
/*
|
||||
* If the user specified "pcie_ports=native", use the PCIe port
|
||||
* services regardless of what _OSC says, i.e., proceed as though the
|
||||
* platform had granted us control of them. "pcie_ports=dpc-native"
|
||||
* does the same for DPC alone. This may conflict with firmware that
|
||||
* expects to own those features.
|
||||
*/
|
||||
if (pcie_ports_native)
|
||||
override = OSC_PCIE_PORT_SERVICE_CONTROLS & ~ctrl;
|
||||
else if (pcie_ports_dpc_native)
|
||||
override = OSC_PCI_EXPRESS_DPC_CONTROL & ~ctrl;
|
||||
|
||||
if (override) {
|
||||
decode_osc_control(root, pcie_ports_native ?
|
||||
"OS forcing control (\"pcie_ports=native\") of" :
|
||||
"OS forcing control (\"pcie_ports=dpc-native\") of",
|
||||
override);
|
||||
ctrl |= override;
|
||||
}
|
||||
|
||||
OSC_OWNER(ctrl, OSC_PCI_EXPRESS_NATIVE_HP_CONTROL,
|
||||
host_bridge->native_pcie_hotplug);
|
||||
OSC_OWNER(ctrl, OSC_PCI_SHPC_NATIVE_HP_CONTROL,
|
||||
host_bridge->native_shpc_hotplug);
|
||||
OSC_OWNER(ctrl, OSC_PCI_EXPRESS_AER_CONTROL, host_bridge->native_aer);
|
||||
OSC_OWNER(ctrl, OSC_PCI_EXPRESS_PME_CONTROL, host_bridge->native_pme);
|
||||
OSC_OWNER(ctrl, OSC_PCI_EXPRESS_LTR_CONTROL, host_bridge->native_ltr);
|
||||
OSC_OWNER(ctrl, OSC_PCI_EXPRESS_DPC_CONTROL, host_bridge->native_dpc);
|
||||
|
||||
OSC_OWNER(ext_ctrl, OSC_CXL_ERROR_REPORTING_CONTROL,
|
||||
host_bridge->native_cxl_error);
|
||||
|
||||
dev_info(&root->device->dev, "OS native features: SHPCHotplug%c PCIeHotplug%c PME%c AER%c DPC%c LTR%c\n",
|
||||
FLAG(host_bridge->native_shpc_hotplug),
|
||||
FLAG(host_bridge->native_pcie_hotplug),
|
||||
FLAG(host_bridge->native_pme),
|
||||
FLAG(host_bridge->native_aer),
|
||||
FLAG(host_bridge->native_dpc),
|
||||
FLAG(host_bridge->native_ltr));
|
||||
|
||||
acpi_dev_power_up_children_with_adr(device);
|
||||
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ static bool pme_is_native(struct pcie_device *dev)
|
|||
const struct pci_host_bridge *host;
|
||||
|
||||
host = pci_find_host_bridge(dev->port->bus);
|
||||
return pcie_ports_native || host->native_pme;
|
||||
return host->native_pme;
|
||||
}
|
||||
|
||||
static void pciehp_disable_interrupt(struct pcie_device *dev)
|
||||
|
|
|
|||
|
|
@ -812,9 +812,6 @@ bool pciehp_is_native(struct pci_dev *bridge)
|
|||
if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
|
||||
return false;
|
||||
|
||||
if (pcie_ports_native)
|
||||
return true;
|
||||
|
||||
host = pci_find_host_bridge(bridge->bus);
|
||||
return host->native_pcie_hotplug;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ int pcie_aer_is_native(struct pci_dev *dev)
|
|||
if (!dev->aer_cap)
|
||||
return 0;
|
||||
|
||||
return pcie_ports_native || host->native_aer;
|
||||
return host->native_aer;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, "CXL");
|
||||
|
||||
|
|
@ -1869,7 +1869,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
|
|||
*/
|
||||
aer = root ? root->aer_cap : 0;
|
||||
|
||||
if ((host->native_aer || pcie_ports_native) && aer)
|
||||
if (host->native_aer && aer)
|
||||
aer_disable_irq(root);
|
||||
|
||||
if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) {
|
||||
|
|
@ -1884,7 +1884,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
|
|||
pci_is_root_bus(dev->bus) ? "Root" : "Downstream", rc);
|
||||
}
|
||||
|
||||
if ((host->native_aer || pcie_ports_native) && aer) {
|
||||
if (host->native_aer && aer) {
|
||||
/* Clear Root Error Status */
|
||||
pci_read_config_dword(root, aer + PCI_ERR_ROOT_STATUS, ®32);
|
||||
pci_write_config_dword(root, aer + PCI_ERR_ROOT_STATUS, reg32);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ static bool cxl_error_is_native(struct pci_dev *dev)
|
|||
{
|
||||
struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
|
||||
|
||||
return (pcie_ports_native || host->native_aer);
|
||||
return host->native_aer;
|
||||
}
|
||||
|
||||
static int cxl_rch_handle_error_iter(struct pci_dev *dev, void *data)
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
|
|||
* it is responsible for clearing this status. In that case, the
|
||||
* signaling device may not even be visible to the OS.
|
||||
*/
|
||||
if (host->native_aer || pcie_ports_native) {
|
||||
if (host->native_aer) {
|
||||
pcie_clear_device_status(dev);
|
||||
pci_aer_clear_nonfatal_status(dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ static int get_port_device_capability(struct pci_dev *dev)
|
|||
if (dev->is_pciehp &&
|
||||
(pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) &&
|
||||
(pcie_ports_native || host->native_pcie_hotplug)) {
|
||||
host->native_pcie_hotplug) {
|
||||
services |= PCIE_PORT_SERVICE_HP;
|
||||
|
||||
/*
|
||||
|
|
@ -240,14 +240,14 @@ static int get_port_device_capability(struct pci_dev *dev)
|
|||
if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
|
||||
dev->aer_cap && pci_aer_available() &&
|
||||
(pcie_ports_native || host->native_aer))
|
||||
host->native_aer)
|
||||
services |= PCIE_PORT_SERVICE_AER;
|
||||
#endif
|
||||
|
||||
/* Root Ports and Root Complex Event Collectors may generate PMEs */
|
||||
if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
|
||||
(pcie_ports_native || host->native_pme)) {
|
||||
host->native_pme) {
|
||||
services |= PCIE_PORT_SERVICE_PME;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
#define PCIE_PORT_DEVICE_MAXSERVICES 5
|
||||
|
||||
extern bool pcie_ports_dpc_native;
|
||||
|
||||
#ifdef CONFIG_PCIEAER
|
||||
int pcie_aer_init(void);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -658,6 +658,8 @@ static const struct device_type pci_host_bridge_type = {
|
|||
|
||||
static void pci_init_host_bridge(struct pci_host_bridge *bridge)
|
||||
{
|
||||
bool port_services = IS_ENABLED(CONFIG_PCIEPORTBUS);
|
||||
|
||||
INIT_LIST_HEAD(&bridge->windows);
|
||||
INIT_LIST_HEAD(&bridge->dma_ranges);
|
||||
INIT_LIST_HEAD(&bridge->ports);
|
||||
|
|
@ -668,12 +670,12 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge)
|
|||
* may implement its own AER handling and use _OSC to prevent the
|
||||
* OS from interfering.
|
||||
*/
|
||||
bridge->native_aer = 1;
|
||||
bridge->native_pcie_hotplug = 1;
|
||||
bridge->native_aer = port_services;
|
||||
bridge->native_pcie_hotplug = port_services;
|
||||
bridge->native_shpc_hotplug = 1;
|
||||
bridge->native_pme = 1;
|
||||
bridge->native_pme = port_services;
|
||||
bridge->native_ltr = 1;
|
||||
bridge->native_dpc = 1;
|
||||
bridge->native_dpc = port_services;
|
||||
bridge->domain_nr = PCI_DOMAIN_NR_NOT_SET;
|
||||
bridge->native_cxl_error = 1;
|
||||
bridge->dev.type = &pci_host_bridge_type;
|
||||
|
|
|
|||
|
|
@ -1915,12 +1915,14 @@ static inline int pci_irqd_intx_xlate(struct irq_domain *d,
|
|||
#ifdef CONFIG_PCIEPORTBUS
|
||||
extern bool pcie_ports_disabled;
|
||||
extern bool pcie_ports_native;
|
||||
extern bool pcie_ports_dpc_native;
|
||||
|
||||
int pcie_set_target_speed(struct pci_dev *port, enum pci_bus_speed speed_req,
|
||||
bool use_lt);
|
||||
#else
|
||||
#define pcie_ports_disabled true
|
||||
#define pcie_ports_native false
|
||||
#define pcie_ports_dpc_native false
|
||||
|
||||
static inline int pcie_set_target_speed(struct pci_dev *port,
|
||||
enum pci_bus_speed speed_req,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user