summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/controller/dwc/Kconfig3
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c4
-rw-r--r--drivers/pci/controller/dwc/pcie-tegra194.c4
-rw-r--r--drivers/pci/controller/mobiveil/pcie-mobiveil-host.c4
-rw-r--r--drivers/pci/controller/pci-aardvark.c3
-rw-r--r--drivers/pci/controller/pci-v3-semi.c4
-rw-r--r--drivers/pci/controller/pcie-mediatek.c3
-rw-r--r--drivers/pci/controller/pcie-tango.c4
-rw-r--r--drivers/pci/hotplug/pciehp.h2
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c2
-rw-r--r--drivers/pci/hotplug/shpchp.h2
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c3
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c5
-rw-r--r--drivers/pci/p2pdma.c2
-rw-r--r--drivers/pci/pci-acpi.c6
-rw-r--r--drivers/pci/pci-label.c4
-rw-r--r--drivers/pci/pci.c64
-rw-r--r--drivers/pci/pcie/Kconfig1
-rw-r--r--drivers/pci/pcie/aer.c340
-rw-r--r--drivers/pci/pcie/aspm.c10
-rw-r--r--drivers/pci/pcie/dpc.c3
-rw-r--r--drivers/pci/pcie/edr.c4
-rw-r--r--drivers/pci/pcie/pme.c4
-rw-r--r--drivers/pci/pcie/portdrv.h13
-rw-r--r--drivers/pci/pcie/ptm.c22
-rw-r--r--drivers/pci/probe.c65
-rw-r--r--drivers/pci/quirks.c50
-rw-r--r--drivers/pci/remove.c2
-rw-r--r--drivers/pci/setup-bus.c114
-rw-r--r--drivers/pci/setup-res.c9
-rw-r--r--drivers/pci/switch/switchtec.c2
31 files changed, 333 insertions, 425 deletions
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 03dcaf65d159..ce13fd62d161 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -26,7 +26,7 @@ config PCI_DRA7XX_HOST
depends on OF && HAS_IOMEM && TI_PIPE3
select PCIE_DW_HOST
select PCI_DRA7XX
- default y
+ default y if SOC_DRA7XX
help
Enables support for the PCIe controller in the DRA7xx SoC to work in
host mode. There are two instances of PCIe controller in DRA7xx.
@@ -111,7 +111,6 @@ config PCI_KEYSTONE_HOST
depends on PCI_MSI_IRQ_DOMAIN
select PCIE_DW_HOST
select PCI_KEYSTONE
- default y
help
Enables support for the PCIe controller in the Keystone SoC to
work in host mode. The PCI controller on Keystone is based on
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index acfbd34032a8..8f08ae53f53e 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -868,9 +868,9 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
if (IS_ENABLED(CONFIG_PCI_MSI)) {
pp->msi_irq = platform_get_irq_byname(pdev, "msi");
- if (pp->msi_irq <= 0) {
+ if (pp->msi_irq < 0) {
dev_err(dev, "failed to get MSI irq\n");
- return -ENODEV;
+ return pp->msi_irq;
}
}
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index ae30a2fd3716..f1f945cc7bcb 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -2190,9 +2190,9 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
}
pp->irq = platform_get_irq_byname(pdev, "intr");
- if (!pp->irq) {
+ if (pp->irq < 0) {
dev_err(dev, "Failed to get \"intr\" interrupt\n");
- return -ENODEV;
+ return pp->irq;
}
pcie->bpmp = tegra_bpmp_get(dev);
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index a94be264240f..5907baa9b1f2 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -522,9 +522,9 @@ static int mobiveil_pcie_integrated_interrupt_init(struct mobiveil_pcie *pcie)
mobiveil_pcie_enable_msi(pcie);
rp->irq = platform_get_irq(pdev, 0);
- if (rp->irq <= 0) {
+ if (rp->irq < 0) {
dev_err(dev, "failed to map IRQ: %d\n", rp->irq);
- return -ENODEV;
+ return rp->irq;
}
/* initialize the IRQ domains */
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index c53ae2511a9c..90ff291c24f0 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1122,6 +1122,9 @@ static int advk_pcie_probe(struct platform_device *pdev)
return PTR_ERR(pcie->base);
irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
ret = devm_request_irq(dev, irq, advk_pcie_irq_handler,
IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie",
pcie);
diff --git a/drivers/pci/controller/pci-v3-semi.c b/drivers/pci/controller/pci-v3-semi.c
index bd05221f5a22..a5bf945d2eda 100644
--- a/drivers/pci/controller/pci-v3-semi.c
+++ b/drivers/pci/controller/pci-v3-semi.c
@@ -777,9 +777,9 @@ static int v3_pci_probe(struct platform_device *pdev)
/* Get and request error IRQ resource */
irq = platform_get_irq(pdev, 0);
- if (irq <= 0) {
+ if (irq < 0) {
dev_err(dev, "unable to obtain PCIv3 error IRQ\n");
- return -ENODEV;
+ return irq;
}
ret = devm_request_irq(dev, irq, v3_irq, 0,
"PCIv3 error", v3);
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index cb982891b22b..ebfa7d5a4e2d 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -651,6 +651,9 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
}
port->irq = platform_get_irq(pdev, port->slot);
+ if (port->irq < 0)
+ return port->irq;
+
irq_set_chained_handler_and_data(port->irq,
mtk_pcie_intr_handler, port);
diff --git a/drivers/pci/controller/pcie-tango.c b/drivers/pci/controller/pcie-tango.c
index 21a208da3f59..18c2c4313eb5 100644
--- a/drivers/pci/controller/pcie-tango.c
+++ b/drivers/pci/controller/pcie-tango.c
@@ -273,9 +273,9 @@ static int tango_pcie_probe(struct platform_device *pdev)
writel_relaxed(0, pcie->base + SMP8759_ENABLE + offset);
virq = platform_get_irq(pdev, 1);
- if (virq <= 0) {
+ if (virq < 0) {
dev_err(dev, "Failed to map IRQ\n");
- return -ENXIO;
+ return virq;
}
irq_dom = irq_domain_create_linear(fwnode, MSI_MAX, &dom_ops, pcie);
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index ae44f46d1bf3..4fd200d8b0a9 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -148,8 +148,6 @@ struct controller {
#define MRL_SENS(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_MRLSP)
#define ATTN_LED(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_AIP)
#define PWR_LED(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_PIP)
-#define HP_SUPR_RM(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_HPS)
-#define EMI(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_EIP)
#define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS)
#define PSN(ctrl) (((ctrl)->slot_cap & PCI_EXP_SLTCAP_PSN) >> 19)
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 6504869efabc..9887c9de08c3 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -435,7 +435,7 @@ static int rpaphp_drc_add_slot(struct device_node *dn)
*/
int rpaphp_add_slot(struct device_node *dn)
{
- if (!dn->name || strcmp(dn->name, "pci"))
+ if (!of_node_name_eq(dn, "pci"))
return 0;
if (of_find_property(dn, "ibm,drc-info", NULL))
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index f7f13ee5d06e..6e85885b554c 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -164,7 +164,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl);
u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl);
u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl);
int shpchp_configure_device(struct slot *p_slot);
-int shpchp_unconfigure_device(struct slot *p_slot);
+void shpchp_unconfigure_device(struct slot *p_slot);
void cleanup_slots(struct controller *ctrl);
void shpchp_queue_pushbutton_work(struct work_struct *work);
int shpc_init(struct controller *ctrl, struct pci_dev *pdev);
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 078003dcde5b..afdc52d1cae7 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -341,8 +341,7 @@ static int remove_board(struct slot *p_slot)
u8 hp_slot;
int rc;
- if (shpchp_unconfigure_device(p_slot))
- return(1);
+ shpchp_unconfigure_device(p_slot);
hp_slot = p_slot->device - ctrl->slot_device_offset;
p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 115701301487..36db0c3c4ea6 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -61,9 +61,8 @@ int shpchp_configure_device(struct slot *p_slot)
return ret;
}
-int shpchp_unconfigure_device(struct slot *p_slot)
+void shpchp_unconfigure_device(struct slot *p_slot)
{
- int rc = 0;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
struct pci_dev *dev, *temp;
struct controller *ctrl = p_slot->ctrl;
@@ -83,6 +82,4 @@ int shpchp_unconfigure_device(struct slot *p_slot)
}
pci_unlock_rescan_remove();
- return rc;
}
-
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index b73b10bce0df..e8e444eeb1cd 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -282,6 +282,8 @@ static const struct pci_p2pdma_whitelist_entry {
} pci_p2pdma_whitelist[] = {
/* AMD ZEN */
{PCI_VENDOR_ID_AMD, 0x1450, 0},
+ {PCI_VENDOR_ID_AMD, 0x15d0, 0},
+ {PCI_VENDOR_ID_AMD, 0x1630, 0},
/* Intel Xeon E5/Core i7 */
{PCI_VENDOR_ID_INTEL, 0x3c00, REQ_SAME_HOST_BRIDGE},
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index d21969fba6ab..7224b1e5f2a8 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -948,7 +948,7 @@ static bool acpi_pci_bridge_d3(struct pci_dev *dev)
* Look for a special _DSD property for the root port and if it
* is set we know the hierarchy behind it supports D3 just fine.
*/
- root = pci_find_pcie_root_port(dev);
+ root = pcie_find_root_port(dev);
if (!root)
return false;
@@ -1128,7 +1128,7 @@ void acpi_pci_add_bus(struct pci_bus *bus)
return;
obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 3,
- RESET_DELAY_DSM, NULL);
+ DSM_PCI_POWER_ON_RESET_DELAY, NULL);
if (!obj)
return;
@@ -1193,7 +1193,7 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev,
pdev->d3cold_delay = 0;
obj = acpi_evaluate_dsm(handle, &pci_acpi_dsm_guid, 3,
- FUNCTION_DELAY_DSM, NULL);
+ DSM_PCI_DEVICE_READINESS_DURATIONS, NULL);
if (!obj)
return;
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
index a5910f942857..707dd9808676 100644
--- a/drivers/pci/pci-label.c
+++ b/drivers/pci/pci-label.c
@@ -178,7 +178,7 @@ static int dsm_get_label(struct device *dev, char *buf,
return -1;
obj = acpi_evaluate_dsm(handle, &pci_acpi_dsm_guid, 0x2,
- DEVICE_LABEL_DSM, NULL);
+ DSM_PCI_DEVICE_NAME, NULL);
if (!obj)
return -1;
@@ -218,7 +218,7 @@ static bool device_has_dsm(struct device *dev)
return false;
return !!acpi_check_dsm(handle, &pci_acpi_dsm_guid, 0x2,
- 1 << DEVICE_LABEL_DSM);
+ 1 << DSM_PCI_DEVICE_NAME);
}
static umode_t acpi_index_string_exist(struct kobject *kobj,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 595fcf59843f..ce096272f52b 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -752,30 +752,6 @@ struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res)
EXPORT_SYMBOL(pci_find_resource);
/**
- * pci_find_pcie_root_port - return PCIe Root Port
- * @dev: PCI device to query
- *
- * Traverse up the parent chain and return the PCIe Root Port PCI Device
- * for a given PCI Device.
- */
-struct pci_dev *pci_find_pcie_root_port(struct pci_dev *dev)
-{
- struct pci_dev *bridge, *highest_pcie_bridge = dev;
-
- bridge = pci_upstream_bridge(dev);
- while (bridge && pci_is_pcie(bridge)) {
- highest_pcie_bridge = bridge;
- bridge = pci_upstream_bridge(bridge);
- }
-
- if (pci_pcie_type(highest_pcie_bridge) != PCI_EXP_TYPE_ROOT_PORT)
- return NULL;
-
- return highest_pcie_bridge;
-}
-EXPORT_SYMBOL(pci_find_pcie_root_port);
-
-/**
* pci_wait_for_pending - wait for @mask bit(s) to clear in status word @pos
* @dev: the PCI device to operate on
* @pos: config space offset of status word
@@ -868,7 +844,9 @@ static inline bool platform_pci_need_resume(struct pci_dev *dev)
static inline bool platform_pci_bridge_d3(struct pci_dev *dev)
{
- return pci_platform_pm ? pci_platform_pm->bridge_d3(dev) : false;
+ if (pci_platform_pm && pci_platform_pm->bridge_d3)
+ return pci_platform_pm->bridge_d3(dev);
+ return false;
}
/**
@@ -1578,7 +1556,7 @@ EXPORT_SYMBOL(pci_restore_state);
struct pci_saved_state {
u32 config_space[16];
- struct pci_cap_saved_data cap[0];
+ struct pci_cap_saved_data cap[];
};
/**
@@ -4660,7 +4638,8 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
* pcie_wait_for_link_delay - Wait until link is active or inactive
* @pdev: Bridge device
* @active: waiting for active or inactive?
- * @delay: Delay to wait after link has become active (in ms)
+ * @delay: Delay to wait after link has become active (in ms). Specify %0
+ * for no delay.
*
* Use this to wait till link becomes active or inactive.
*/
@@ -4673,10 +4652,10 @@ static bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active,
/*
* Some controllers might not implement link active reporting. In this
- * case, we wait for 1000 + 100 ms.
+ * case, we wait for 1000 ms + any delay requested by the caller.
*/
if (!pdev->link_active_reporting) {
- msleep(1100);
+ msleep(timeout + delay);
return true;
}
@@ -4701,7 +4680,7 @@ static bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active,
msleep(10);
timeout -= 10;
}
- if (active && ret)
+ if (active && ret && delay)
msleep(delay);
else if (ret != active)
pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n",
@@ -4822,17 +4801,28 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev)
if (!pcie_downstream_port(dev))
return;
- if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) {
- pci_dbg(dev, "waiting %d ms for downstream link\n", delay);
- msleep(delay);
- } else {
- pci_dbg(dev, "waiting %d ms for downstream link, after activation\n",
- delay);
- if (!pcie_wait_for_link_delay(dev, true, delay)) {
+ /*
+ * Per PCIe r5.0, sec 6.6.1, for downstream ports that support
+ * speeds > 5 GT/s, we must wait for link training to complete
+ * before the mandatory delay.
+ *
+ * We can only tell when link training completes via DLL Link
+ * Active, which is required for downstream ports that support
+ * speeds > 5 GT/s (sec 7.5.3.6). Unfortunately some common
+ * devices do not implement Link Active reporting even when it's
+ * required, so we'll check for that directly instead of checking
+ * the supported link speed. We assume devices without Link Active
+ * reporting can train in 100 ms regardless of speed.
+ */
+ if (dev->link_active_reporting) {
+ pci_dbg(dev, "waiting for link to train\n");
+ if (!pcie_wait_for_link_delay(dev, true, 0)) {
/* Did not train, no need to wait any further */
return;
}
}
+ pci_dbg(child, "waiting %d ms to become accessible\n", delay);
+ msleep(delay);
if (!pci_device_is_present(child)) {
pci_dbg(child, "waiting additional %d ms to become accessible\n", delay);
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index 66386811cfde..9cd31331aee9 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -25,7 +25,6 @@ config PCIEAER
bool "PCI Express Advanced Error Reporting support"
depends on PCIEPORTBUS
select RAS
- default y
help
This enables PCI Express Root Port Advanced Error Reporting
(AER) driver support. Error reporting messages sent to Root
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index f4274d301235..3acf56683915 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -136,22 +136,18 @@ static const char * const ecrc_policy_str[] = {
*/
static int enable_ecrc_checking(struct pci_dev *dev)
{
- int pos;
+ int aer = dev->aer_cap;
u32 reg32;
- if (!pci_is_pcie(dev))
+ if (!aer)
return -ENODEV;
- pos = dev->aer_cap;
- if (!pos)
- return -ENODEV;
-
- pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
+ pci_read_config_dword(dev, aer + PCI_ERR_CAP, &reg32);
if (reg32 & PCI_ERR_CAP_ECRC_GENC)
reg32 |= PCI_ERR_CAP_ECRC_GENE;
if (reg32 & PCI_ERR_CAP_ECRC_CHKC)
reg32 |= PCI_ERR_CAP_ECRC_CHKE;
- pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
+ pci_write_config_dword(dev, aer + PCI_ERR_CAP, reg32);
return 0;
}
@@ -164,19 +160,15 @@ static int enable_ecrc_checking(struct pci_dev *dev)
*/
static int disable_ecrc_checking(struct pci_dev *dev)
{
- int pos;
+ int aer = dev->aer_cap;
u32 reg32;
- if (!pci_is_pcie(dev))
+ if (!aer)
return -ENODEV;
- pos = dev->aer_cap;
- if (!pos)
- return -ENODEV;
-
- pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
+ pci_read_config_dword(dev, aer + PCI_ERR_CAP, &reg32);
reg32 &= ~(PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE);
- pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
+ pci_write_config_dword(dev, aer + PCI_ERR_CAP, reg32);
return 0;
}
@@ -217,142 +209,22 @@ void pcie_ecrc_get_policy(char *str)
}
#endif /* CONFIG_PCIE_ECRC */
-#ifdef CONFIG_ACPI_APEI
-static inline int hest_match_pci(struct acpi_hest_aer_common *p,
- struct pci_dev *pci)
-{
- return ACPI_HEST_SEGMENT(p->bus) == pci_domain_nr(pci->bus) &&
- ACPI_HEST_BUS(p->bus) == pci->bus->number &&
- p->device == PCI_SLOT(pci->devfn) &&
- p->function == PCI_FUNC(pci->devfn);
-}
-
-static inline bool hest_match_type(struct acpi_hest_header *hest_hdr,
- struct pci_dev *dev)
-{
- u16 hest_type = hest_hdr->type;
- u8 pcie_type = pci_pcie_type(dev);
-
- if ((hest_type == ACPI_HEST_TYPE_AER_ROOT_PORT &&
- pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
- (hest_type == ACPI_HEST_TYPE_AER_ENDPOINT &&
- pcie_type == PCI_EXP_TYPE_ENDPOINT) ||
- (hest_type == ACPI_HEST_TYPE_AER_BRIDGE &&
- (dev->class >> 16) == PCI_BASE_CLASS_BRIDGE))
- return true;
- return false;
-}
-
-struct aer_hest_parse_info {
- struct pci_dev *pci_dev;
- int firmware_first;
-};
-
-static int hest_source_is_pcie_aer(struct acpi_hest_header *hest_hdr)
-{
- if (hest_hdr->type == ACPI_HEST_TYPE_AER_ROOT_PORT ||
- hest_hdr->type == ACPI_HEST_TYPE_AER_ENDPOINT ||
- hest_hdr->type == ACPI_HEST_TYPE_AER_BRIDGE)
- return 1;
- return 0;
-}
-
-static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data)
-{
- struct aer_hest_parse_info *info = data;
- struct acpi_hest_aer_common *p;
- int ff;
-
- if (!hest_source_is_pcie_aer(hest_hdr))
- return 0;
-
- p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
- ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
-
- /*
- * If no specific device is supplied, determine whether
- * FIRMWARE_FIRST is set for *any* PCIe device.
- */
- if (!info->pci_dev) {
- info->firmware_first |= ff;
- return 0;
- }
-
- /* Otherwise, check the specific device */
- if (p->flags & ACPI_HEST_GLOBAL) {
- if (hest_match_type(hest_hdr, info->pci_dev))
- info->firmware_first = ff;
- } else
- if (hest_match_pci(p, info->pci_dev))
- info->firmware_first = ff;
-
- return 0;
-}
-
-static void aer_set_firmware_first(struct pci_dev *pci_dev)
-{
- int rc;
- struct aer_hest_parse_info info = {
- .pci_dev = pci_dev,
- .firmware_first = 0,
- };
-
- rc = apei_hest_parse(aer_hest_parse, &info);
-
- if (rc)
- pci_dev->__aer_firmware_first = 0;
- else
- pci_dev->__aer_firmware_first = info.firmware_first;
- pci_dev->__aer_firmware_first_valid = 1;
-}
+#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
+ PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
-int pcie_aer_get_firmware_first(struct pci_dev *dev)
+int pcie_aer_is_native(struct pci_dev *dev)
{
- if (!pci_is_pcie(dev))
- return 0;
+ struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
- if (pcie_ports_native)
+ if (!dev->aer_cap)
return 0;
- if (!dev->__aer_firmware_first_valid)
- aer_set_firmware_first(dev);
- return dev->__aer_firmware_first;
-}
-
-static bool aer_firmware_first;
-
-/**
- * aer_acpi_firmware_first - Check if APEI should control AER.
- */
-bool aer_acpi_firmware_first(void)
-{
- static bool parsed = false;
- struct aer_hest_parse_info info = {
- .pci_dev = NULL, /* Check all PCIe devices */
- .firmware_first = 0,
- };
-
- if (pcie_ports_native)
- return false;
-
- if (!parsed) {
- apei_hest_parse(aer_hest_parse, &info);
- aer_firmware_first = info.firmware_first;
- parsed = true;
- }
- return aer_firmware_first;
+ return pcie_ports_native || host->native_aer;
}
-#endif
-
-#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
- PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
- if (pcie_aer_get_firmware_first(dev))
- return -EIO;
-
- if (!dev->aer_cap)
+ if (!pcie_aer_is_native(dev))
return -EIO;
return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
@@ -361,7 +233,7 @@ EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
int pci_disable_pcie_error_reporting(struct pci_dev *dev)
{
- if (pcie_aer_get_firmware_first(dev))
+ if (!pcie_aer_is_native(dev))
return -EIO;
return pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
@@ -379,22 +251,18 @@ void pci_aer_clear_device_status(struct pci_dev *dev)
int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
{
- int pos;
+ int aer = dev->aer_cap;
u32 status, sev;
- pos = dev->aer_cap;
- if (!pos)
- return -EIO;
-
- if (pcie_aer_get_firmware_first(dev))
+ if (!pcie_aer_is_native(dev))
return -EIO;
/* Clear status bits for ERR_NONFATAL errors only */
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &sev);
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS, &status);
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_SEVER, &sev);
status &= ~sev;
if (status)
- pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
+ pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS, status);
return 0;
}
@@ -402,22 +270,18 @@ EXPORT_SYMBOL_GPL(pci_aer_clear_nonfatal_status);
void pci_aer_clear_fatal_status(struct pci_dev *dev)
{
- int pos;
+ int aer = dev->aer_cap;
u32 status, sev;
- pos = dev->aer_cap;
- if (!pos)
- return;
-
- if (pcie_aer_get_firmware_first(dev))
+ if (!pcie_aer_is_native(dev))
return;
/* Clear status bits for ERR_FATAL errors only */
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &sev);
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS, &status);
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_SEVER, &sev);
status &= sev;
if (status)
- pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
+ pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS, status);
}
/**
@@ -431,35 +295,31 @@ void pci_aer_clear_fatal_status(struct pci_dev *dev)
*/
int pci_aer_raw_clear_status(struct pci_dev *dev)
{
- int pos;
+ int aer = dev->aer_cap;
u32 status;
int port_type;
- if (!pci_is_pcie(dev))
- return -ENODEV;
-
- pos = dev->aer_cap;
- if (!pos)
+ if (!aer)
return -EIO;
port_type = pci_pcie_type(dev);
if (port_type == PCI_EXP_TYPE_ROOT_PORT) {
- pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &status);
- pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, status);
+ pci_read_config_dword(dev, aer + PCI_ERR_ROOT_STATUS, &status);
+ pci_write_config_dword(dev, aer + PCI_ERR_ROOT_STATUS, status);
}
- pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
- pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status);
+ pci_read_config_dword(dev, aer + PCI_ERR_COR_STATUS, &status);
+ pci_write_config_dword(dev, aer + PCI_ERR_COR_STATUS, status);
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
- pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS, &status);
+ pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS, status);
return 0;
}
int pci_aer_clear_status(struct pci_dev *dev)
{
- if (pcie_aer_get_firmware_first(dev))
+ if (!pcie_aer_is_native(dev))
return -EIO;
return pci_aer_raw_clear_status(dev);
@@ -467,12 +327,11 @@ int pci_aer_clear_status(struct pci_dev *dev)
void pci_save_aer_state(struct pci_dev *dev)
{
+ int aer = dev->aer_cap;
struct pci_cap_saved_state *save_state;
u32 *cap;
- int pos;
- pos = dev->aer_cap;
- if (!pos)
+ if (!aer)
return;
save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_ERR);
@@ -480,22 +339,21 @@ void pci_save_aer_state(struct pci_dev *dev)
return;
cap = &save_state->cap.data[0];
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, cap++);
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, cap++);
- pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, cap++);
- pci_read_config_dword(dev, pos + PCI_ERR_CAP, cap++);
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, cap++);
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_SEVER, cap++);
+ pci_read_config_dword(dev, aer + PCI_ERR_COR_MASK, cap++);
+ pci_read_config_dword(dev, aer + PCI_ERR_CAP, cap++);
if (pcie_cap_has_rtctl(dev))
- pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, cap++);
+ pci_read_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, cap++);
}
void pci_restore_aer_state(struct pci_dev *dev)
{
+ int aer = dev->aer_cap;
struct pci_cap_saved_state *save_state;
u32 *cap;
- int pos;
- pos = dev->aer_cap;
- if (!pos)
+ if (!aer)
return;
save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_ERR);
@@ -503,12 +361,12 @@ void pci_restore_aer_state(struct pci_dev *dev)
return;
cap = &save_state->cap.data[0];
- pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, *cap++);
- pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, *cap++);
- pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, *cap++);
- pci_write_config_dword(dev, pos + PCI_ERR_CAP, *cap++);
+ pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, *cap++);
+ pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_SEVER, *cap++);
+ pci_write_config_dword(dev, aer + PCI_ERR_COR_MASK, *cap++);
+ pci_write_config_dword(dev, aer + PCI_ERR_CAP, *cap++);
if (pcie_cap_has_rtctl(dev))
- pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, *cap++);
+ pci_write_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, *cap++);
}
void pci_aer_init(struct pci_dev *dev)
@@ -939,7 +797,7 @@ static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev)
*/
static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
{
- int pos;
+ int aer = dev->aer_cap;
u32 status, mask;
u16 reg16;
@@ -974,17 +832,16 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
if (!(reg16 & PCI_EXP_AER_FLAGS))
return false;
- pos = dev->aer_cap;
- if (!pos)
+ if (!aer)
return false;
/* Check if error is recorded */
if (e_info->severity == AER_CORRECTABLE) {
- pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
- pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &mask);
+ pci_read_config_dword(dev, aer + PCI_ERR_COR_STATUS, &status);
+ pci_read_config_dword(dev, aer + PCI_ERR_COR_MASK, &mask);
} else {
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask);
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS, &status);
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &mask);
}
if (status & ~mask)
return true;
@@ -1055,16 +912,15 @@ static bool find_source_device(struct pci_dev *parent,
*/
static void handle_error_source(struct pci_dev *dev, struct aer_err_info *info)
{
- int pos;
+ int aer = dev->aer_cap;
if (info->severity == AER_CORRECTABLE) {
/*
* Correctable error does not need software intervention.
* No need to go through error recovery process.
*/
- pos = dev->aer_cap;
- if (pos)
- pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
+ if (aer)
+ pci_write_config_dword(dev, aer + PCI_ERR_COR_STATUS,
info->status);
pci_aer_clear_device_status(dev);
} else if (info->severity == AER_NONFATAL)
@@ -1155,22 +1011,21 @@ EXPORT_SYMBOL_GPL(aer_recover_queue);
*/
int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
{
- int pos, temp;
+ int aer = dev->aer_cap;
+ int temp;
/* Must reset in this function */
info->status = 0;
info->tlp_header_valid = 0;
- pos = dev->aer_cap;
-
/* The device might not support AER */
- if (!pos)
+ if (!aer)
return 0;
if (info->severity == AER_CORRECTABLE) {
- pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS,
+ pci_read_config_dword(dev, aer + PCI_ERR_COR_STATUS,
&info->status);
- pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK,
+ pci_read_config_dword(dev, aer + PCI_ERR_COR_MASK,
&info->mask);
if (!(info->status & ~info->mask))
return 0;
@@ -1179,27 +1034,27 @@ int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
info->severity == AER_NONFATAL) {
/* Link is still healthy for IO reads */
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS,
&info->status);
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK,
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK,
&info->mask);
if (!(info->status & ~info->mask))
return 0;
/* Get First Error Pointer */
- pci_read_config_dword(dev, pos + PCI_ERR_CAP, &temp);
+ pci_read_config_dword(dev, aer + PCI_ERR_CAP, &temp);
info->first_error = PCI_ERR_CAP_FEP(temp);
if (info->status & AER_LOG_TLP_MASKS) {
info->tlp_header_valid = 1;
pci_read_config_dword(dev,
- pos + PCI_ERR_HEADER_LOG, &info->tlp.dw0);
+ aer + PCI_ERR_HEADER_LOG, &info->tlp.dw0);
pci_read_config_dword(dev,
- pos + PCI_ERR_HEADER_LOG + 4, &info->tlp.dw1);
+ aer + PCI_ERR_HEADER_LOG + 4, &info->tlp.dw1);
pci_read_config_dword(dev,
- pos + PCI_ERR_HEADER_LOG + 8, &info->tlp.dw2);
+ aer + PCI_ERR_HEADER_LOG + 8, &info->tlp.dw2);
pci_read_config_dword(dev,
- pos + PCI_ERR_HEADER_LOG + 12, &info->tlp.dw3);
+ aer + PCI_ERR_HEADER_LOG + 12, &info->tlp.dw3);
}
}
@@ -1305,15 +1160,15 @@ static irqreturn_t aer_irq(int irq, void *context)
struct pcie_device *pdev = (struct pcie_device *)context;
struct aer_rpc *rpc = get_service_data(pdev);
struct pci_dev *rp = rpc->rpd;
+ int aer = rp->aer_cap;
struct aer_err_source e_src = {};
- int pos = rp->aer_cap;
- pci_read_config_dword(rp, pos + PCI_ERR_ROOT_STATUS, &e_src.status);
+ pci_read_config_dword(rp, aer + PCI_ERR_ROOT_STATUS, &e_src.status);
if (!(e_src.status & (PCI_ERR_ROOT_UNCOR_RCV|PCI_ERR_ROOT_COR_RCV)))
return IRQ_NONE;
- pci_read_config_dword(rp, pos + PCI_ERR_ROOT_ERR_SRC, &e_src.id);
- pci_write_config_dword(rp, pos + PCI_ERR_ROOT_STATUS, e_src.status);
+ pci_read_config_dword(rp, aer + PCI_ERR_ROOT_ERR_SRC, &e_src.id);
+ pci_write_config_dword(rp, aer + PCI_ERR_ROOT_STATUS, e_src.status);
if (!kfifo_put(&rpc->aer_fifo, e_src))
return IRQ_HANDLED;
@@ -1365,7 +1220,7 @@ static void set_downstream_devices_error_reporting(struct pci_dev *dev,
static void aer_enable_rootport(struct aer_rpc *rpc)
{
struct pci_dev *pdev = rpc->rpd;
- int aer_pos;
+ int aer = pdev->aer_cap;
u16 reg16;
u32 reg32;
@@ -1377,14 +1232,13 @@ static void aer_enable_rootport(struct aer_rpc *rpc)
pcie_capability_clear_word(pdev, PCI_EXP_RTCTL,
SYSTEM_ERROR_INTR_ON_MESG_MASK);
- aer_pos = pdev->aer_cap;
/* Clear error status */
- pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
- pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
- pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, &reg32);
- pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32);
- pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32);
- pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);
+ pci_read_config_dword(pdev, aer + PCI_ERR_ROOT_STATUS, &reg32);
+ pci_write_config_dword(pdev, aer + PCI_ERR_ROOT_STATUS, reg32);
+ pci_read_config_dword(pdev, aer + PCI_ERR_COR_STATUS, &reg32);
+ pci_write_config_dword(pdev, aer + PCI_ERR_COR_STATUS, reg32);
+ pci_read_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS, &reg32);
+ pci_write_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS, reg32);
/*
* Enable error reporting for the root port device and downstream port
@@ -1393,9 +1247,9 @@ static void aer_enable_rootport(struct aer_rpc *rpc)
set_downstream_devices_error_reporting(pdev, true);
/* Enable Root Port's interrupt in response to error messages */
- pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, &reg32);
+ pci_read_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, &reg32);
reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
- pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, reg32);
+ pci_write_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, reg32);
}
/**
@@ -1407,8 +1261,8 @@ static void aer_enable_rootport(struct aer_rpc *rpc)
static void aer_disable_rootport(struct aer_rpc *rpc)
{
struct pci_dev *pdev = rpc->rpd;
+ int aer = pdev->aer_cap;
u32 reg32;
- int pos;
/*
* Disable error reporting for the root port device and downstream port
@@ -1416,15 +1270,14 @@ static void aer_disable_rootport(struct aer_rpc *rpc)
*/
set_downstream_devices_error_reporting(pdev, false);
- pos = pdev->aer_cap;
/* Disable Root's interrupt in response to error messages */
- pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
+ pci_read_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, &reg32);
reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
- pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, reg32);
+ pci_write_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, reg32);
/* Clear Root's error status reg */
- pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, &reg32);
- pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, reg32);
+ pci_read_config_dword(pdev, aer + PCI_ERR_ROOT_STATUS, &reg32);
+ pci_write_config_dword(pdev, aer + PCI_ERR_ROOT_STATUS, reg32);
}
/**
@@ -1481,28 +1334,27 @@ static int aer_probe(struct pcie_device *dev)
*/
static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
{
+ int aer = dev->aer_cap;
u32 reg32;
- int pos;
int rc;
- pos = dev->aer_cap;
/* Disable Root's interrupt in response to error messages */
- pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
+ pci_read_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, &reg32);
reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
- pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32);
+ pci_write_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, reg32);
rc = pci_bus_error_reset(dev);
pci_info(dev, "Root Port link has been reset\n");
/* Clear Root Error Status */
- pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
- pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, reg32);
+ pci_read_config_dword(dev, aer + PCI_ERR_ROOT_STATUS, &reg32);
+ pci_write_config_dword(dev, aer + PCI_ERR_ROOT_STATUS, reg32);
/* Enable Root Port's interrupt in response to error messages */
- pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
+ pci_read_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, &reg32);
reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
- pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32);
+ pci_write_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, reg32);
return rc ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
}
@@ -1523,7 +1375,7 @@ static struct pcie_port_service_driver aerdriver = {
*/
int __init pcie_aer_init(void)
{
- if (!pci_aer_available() || aer_acpi_firmware_first())
+ if (!pci_aer_available())
return -ENXIO;
return pcie_port_service_register(&aerdriver);
}
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 2378ed692534..b17e5ffd31b1 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -628,16 +628,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
/* Setup initial capable state. Will be updated later */
link->aspm_capable = link->aspm_support;
- /*
- * If the downstream component has pci bridge function, don't
- * do ASPM for now.
- */
- list_for_each_entry(child, &linkbus->devices, bus_list) {
- if (pci_pcie_type(child) == PCI_EXP_TYPE_PCI_BRIDGE) {
- link->aspm_disable = ASPM_STATE_ALL;
- break;
- }
- }
/* Get and check endpoint acceptable latencies */
list_for_each_entry(child, &linkbus->devices, bus_list) {
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 762170423fdd..daa9a4153776 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -284,7 +284,7 @@ static int dpc_probe(struct pcie_device *dev)
int status;
u16 ctl, cap;
- if (pcie_aer_get_firmware_first(pdev) && !pcie_ports_dpc_native)
+ if (!pcie_aer_is_native(pdev) && !pcie_ports_dpc_native)
return -ENOTSUPP;
status = devm_request_threaded_irq(device, dev->irq, dpc_irq,
@@ -301,6 +301,7 @@ static int dpc_probe(struct pcie_device *dev)
ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN;
pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl);
+ pci_info(pdev, "enabled with IRQ %d\n", dev->irq);
pci_info(pdev, "error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n",
cap & PCI_EXP_DPC_IRQ, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT),
diff --git a/drivers/pci/pcie/edr.c b/drivers/pci/pcie/edr.c
index 594622a6cb16..a6b9b479b97a 100644
--- a/drivers/pci/pcie/edr.c
+++ b/drivers/pci/pcie/edr.c
@@ -148,11 +148,11 @@ static void edr_handle_event(acpi_handle handle, u32 event, void *data)
pci_ers_result_t estate = PCI_ERS_RESULT_DISCONNECT;
u16 status;
- pci_info(pdev, "ACPI event %#x received\n", event);
-
if (event != ACPI_NOTIFY_DISCONNECT_RECOVER)
return;
+ pci_info(pdev, "EDR event received\n");
+
/* Locate the port which issued EDR event */
edev = acpi_dpc_port_get(pdev);
if (!edev) {
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index f38e6c19dd50..6a32970bb731 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -408,7 +408,7 @@ static int pcie_pme_suspend(struct pcie_device *srv)
/**
* pcie_pme_resume - Resume PCIe PME service device.
- * @srv - PCIe service device to resume.
+ * @srv: PCIe service device to resume.
*/
static int pcie_pme_resume(struct pcie_device *srv)
{
@@ -431,7 +431,7 @@ static int pcie_pme_resume(struct pcie_device *srv)
/**
* pcie_pme_remove - Prepare PCIe PME service device for removal.
- * @srv - PCIe service device to remove.
+ * @srv: PCIe service device to remove.
*/
static void pcie_pme_remove(struct pcie_device *srv)
{
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 64b5e081cdb2..af7cf237432a 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -29,8 +29,10 @@ extern bool pcie_ports_dpc_native;
#ifdef CONFIG_PCIEAER
int pcie_aer_init(void);
+int pcie_aer_is_native(struct pci_dev *dev);
#else
static inline int pcie_aer_init(void) { return 0; }
+static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }
#endif
#ifdef CONFIG_HOTPLUG_PCI_PCIE
@@ -147,16 +149,5 @@ static inline bool pcie_pme_no_msi(void) { return false; }
static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {}
#endif /* !CONFIG_PCIE_PME */
-#ifdef CONFIG_ACPI_APEI
-int pcie_aer_get_firmware_first(struct pci_dev *pci_dev);
-#else
-static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
-{
- if (pci_dev->__aer_firmware_first_valid)
- return pci_dev->__aer_firmware_first;
- return 0;
-}
-#endif
-
struct device *pcie_port_find_device(struct pci_dev *dev, u32 service);
#endif /* _PORTDRV_H_ */
diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c
index 9361f3aa26ab..357a454cafa0 100644
--- a/drivers/pci/pcie/ptm.c
+++ b/drivers/pci/pcie/ptm.c
@@ -39,10 +39,6 @@ void pci_ptm_init(struct pci_dev *dev)
if (!pci_is_pcie(dev))
return;
- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM);
- if (!pos)
- return;
-
/*
* Enable PTM only on interior devices (root ports, switch ports,
* etc.) on the assumption that it causes no link traffic until an
@@ -52,6 +48,23 @@ void pci_ptm_init(struct pci_dev *dev)
pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END))
return;
+ /*
+ * Switch Downstream Ports are not permitted to have a PTM
+ * capability; their PTM behavior is controlled by the Upstream
+ * Port (PCIe r5.0, sec 7.9.16).
+ */
+ ups = pci_upstream_bridge(dev);
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM &&
+ ups && ups->ptm_enabled) {
+ dev->ptm_granularity = ups->ptm_granularity;
+ dev->ptm_enabled = 1;
+ return;
+ }
+
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM);
+ if (!pos)
+ return;
+
pci_read_config_dword(dev, pos + PCI_PTM_CAP, &cap);
local_clock = (cap & PCI_PTM_GRANULARITY_MASK) >> 8;
@@ -61,7 +74,6 @@ void pci_ptm_init(struct pci_dev *dev)
* the spec recommendation (PCIe r3.1, sec 7.32.3), select the
* furthest upstream Time Source as the PTM Root.
*/
- ups = pci_upstream_bridge(dev);
if (ups && ups->ptm_enabled) {
ctrl = PCI_PTM_CTRL_ENABLE;
if (ups->ptm_granularity == 0)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 77b8a145c39b..dd8839180afb 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -565,7 +565,7 @@ static struct pci_bus *pci_alloc_bus(struct pci_bus *parent)
return b;
}
-static void devm_pci_release_host_bridge_dev(struct device *dev)
+static void pci_release_host_bridge_dev(struct device *dev)
{
struct pci_host_bridge *bridge = to_pci_host_bridge(dev);
@@ -574,12 +574,7 @@ static void devm_pci_release_host_bridge_dev(struct device *dev)
pci_free_resource_list(&bridge->windows);
pci_free_resource_list(&bridge->dma_ranges);
-}
-
-static void pci_release_host_bridge_dev(struct device *dev)
-{
- devm_pci_release_host_bridge_dev(dev);
- kfree(to_pci_host_bridge(dev));
+ kfree(bridge);
}
static void pci_init_host_bridge(struct pci_host_bridge *bridge)
@@ -599,6 +594,8 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge)
bridge->native_pme = 1;
bridge->native_ltr = 1;
bridge->native_dpc = 1;
+
+ device_initialize(&bridge->dev);
}
struct pci_host_bridge *pci_alloc_host_bridge(size_t priv)
@@ -616,17 +613,25 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv)
}
EXPORT_SYMBOL(pci_alloc_host_bridge);
+static void devm_pci_alloc_host_bridge_release(void *data)
+{
+ pci_free_host_bridge(data);
+}
+
struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev,
size_t priv)
{
+ int ret;
struct pci_host_bridge *bridge;
- bridge = devm_kzalloc(dev, sizeof(*bridge) + priv, GFP_KERNEL);
+ bridge = pci_alloc_host_bridge(priv);
if (!bridge)
return NULL;
- pci_init_host_bridge(bridge);
- bridge->dev.release = devm_pci_release_host_bridge_dev;
+ ret = devm_add_action_or_reset(dev, devm_pci_alloc_host_bridge_release,
+ bridge);
+ if (ret)
+ return NULL;
return bridge;
}
@@ -634,10 +639,7 @@ EXPORT_SYMBOL(devm_pci_alloc_host_bridge);
void pci_free_host_bridge(struct pci_host_bridge *bridge)
{
- pci_free_resource_list(&bridge->windows);
- pci_free_resource_list(&bridge->dma_ranges);
-
- kfree(bridge);
+ put_device(&bridge->dev);
}
EXPORT_SYMBOL(pci_free_host_bridge);
@@ -908,10 +910,11 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
if (err)
goto free;
- err = device_register(&bridge->dev);
- if (err)
+ err = device_add(&bridge->dev);
+ if (err) {
put_device(&bridge->dev);
-
+ goto free;
+ }
bus->bridge = get_device(&bridge->dev);
device_enable_async_suspend(bus->bridge);
pci_set_bus_of_node(bus);
@@ -977,7 +980,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
unregister:
put_device(&bridge->dev);
- device_unregister(&bridge->dev);
+ device_del(&bridge->dev);
free:
kfree(bus);
@@ -1934,13 +1937,33 @@ static void pci_configure_mps(struct pci_dev *dev)
struct pci_dev *bridge = pci_upstream_bridge(dev);
int mps, mpss, p_mps, rc;
- if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge))
+ if (!pci_is_pcie(dev))
return;
/* MPS and MRRS fields are of type 'RsvdP' for VFs, short-circuit out */
if (dev->is_virtfn)
return;
+ /*
+ * For Root Complex Integrated Endpoints, program the maximum
+ * supported value unless limited by the PCIE_BUS_PEER2PEER case.
+ */
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) {
+ if (pcie_bus_config == PCIE_BUS_PEER2PEER)
+ mps = 128;
+ else
+ mps = 128 << dev->pcie_mpss;
+ rc = pcie_set_mps(dev, mps);
+ if (rc) {
+ pci_warn(dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+ mps);
+ }
+ return;
+ }
+
+ if (!bridge || !pci_is_pcie(bridge))
+ return;
+
mps = pcie_get_mps(dev);
p_mps = pcie_get_mps(bridge);
@@ -2056,7 +2079,7 @@ static void pci_configure_relaxed_ordering(struct pci_dev *dev)
* For now, we only deal with Relaxed Ordering issues with Root
* Ports. Peer-to-Peer DMA is another can of worms.
*/
- root = pci_find_pcie_root_port(dev);
+ root = pcie_find_root_port(dev);
if (!root)
return;
@@ -2952,7 +2975,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
return bridge->bus;
err_out:
- kfree(bridge);
+ put_device(&bridge->dev);
return NULL;
}
EXPORT_SYMBOL_GPL(pci_create_root_bus);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 28c9a2409c50..97df1f90160d 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4319,7 +4319,7 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, 0x1a02, PCI_CLASS_NOT_DEFINED,
*/
static void quirk_disable_root_port_attributes(struct pci_dev *pdev)
{
- struct pci_dev *root_port = pci_find_pcie_root_port(pdev);
+ struct pci_dev *root_port = pcie_find_root_port(pdev);
if (!root_port) {
pci_warn(pdev, "PCIe Completion erratum may cause device errors\n");
@@ -4682,6 +4682,20 @@ static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags)
PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT);
}
+static int pci_quirk_rciep_acs(struct pci_dev *dev, u16 acs_flags)
+{
+ /*
+ * Intel RCiEP's are required to allow p2p only on translated
+ * addresses. Refer to Intel VT-d specification, r3.1, sec 3.16,
+ * "Root-Complex Peer to Peer Considerations".
+ */
+ if (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_END)
+ return -ENOTTY;
+
+ return pci_acs_ctrl_enabled(acs_flags,
+ PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
+}
+
static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags)
{
/*
@@ -4764,6 +4778,7 @@ static const struct pci_dev_acs_enabled {
/* I219 */
{ PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs },
{ PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs },
+ { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_rciep_acs },
/* QCOM QDF2xxx root ports */
{ PCI_VENDOR_ID_QCOM, 0x0400, pci_quirk_qcom_rp_acs },
{ PCI_VENDOR_ID_QCOM, 0x0401, pci_quirk_qcom_rp_acs },
@@ -5129,13 +5144,25 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap);
-/* FLR may cause some 82579 devices to hang */
-static void quirk_intel_no_flr(struct pci_dev *dev)
+/*
+ * FLR may cause the following to devices to hang:
+ *
+ * AMD Starship/Matisse HD Audio Controller 0x1487
+ * AMD Starship USB 3.0 Host Controller 0x148c
+ * AMD Matisse USB 3.0 Host Controller 0x149c
+ * Intel 82579LM Gigabit Ethernet Controller 0x1502
+ * Intel 82579V Gigabit Ethernet Controller 0x1503
+ *
+ */
+static void quirk_no_flr(struct pci_dev *dev)
{
dev->dev_flags |= PCI_DEV_FLAGS_NO_FLR_RESET;
}
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_intel_no_flr);
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_intel_no_flr);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1487, quirk_no_flr);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x148c, quirk_no_flr);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x149c, quirk_no_flr);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_no_flr);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_no_flr);
static void quirk_no_ext_tags(struct pci_dev *pdev)
{
@@ -5567,3 +5594,16 @@ static void pci_fixup_no_d0_pme(struct pci_dev *dev)
dev->pme_support &= ~(PCI_PM_CAP_PME_D0 >> PCI_PM_CAP_PME_SHIFT);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x2142, pci_fixup_no_d0_pme);
+
+/*
+ * Device [12d8:0x400e] and [12d8:0x400f]
+ * These devices advertise PME# support in all power states but don't
+ * reliably assert it.
+ */
+static void pci_fixup_no_pme(struct pci_dev *dev)
+{
+ pci_info(dev, "PME# is unreliable, disabling it\n");
+ dev->pme_support = 0;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_PERICOM, 0x400e, pci_fixup_no_pme);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_PERICOM, 0x400f, pci_fixup_no_pme);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index e9c6b120cf45..95dec03d9f2a 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -160,6 +160,6 @@ void pci_remove_root_bus(struct pci_bus *bus)
host_bridge->bus = NULL;
/* remove the host bridge */
- device_unregister(&host_bridge->dev);
+ device_del(&host_bridge->dev);
}
EXPORT_SYMBOL_GPL(pci_remove_root_bus);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index bbcef1a053ab..07cd7a3817dc 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -583,7 +583,7 @@ static void pci_setup_bridge_io(struct pci_dev *bridge)
io_mask = PCI_IO_1K_RANGE_MASK;
/* Set up the top and bottom of the PCI I/O segment for this bus */
- res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
+ res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
pcibios_resource_to_bus(bridge->bus, &region, res);
if (res->flags & IORESOURCE_IO) {
pci_read_config_word(bridge, PCI_IO_BASE, &l);
@@ -613,7 +613,7 @@ static void pci_setup_bridge_mmio(struct pci_dev *bridge)
u32 l;
/* Set up the top and bottom of the PCI Memory segment for this bus */
- res = &bridge->resource[PCI_BRIDGE_RESOURCES + 1];
+ res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW];
pcibios_resource_to_bus(bridge->bus, &region, res);
if (res->flags & IORESOURCE_MEM) {
l = (region.start >> 16) & 0xfff0;
@@ -640,7 +640,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge)
/* Set up PREF base/limit */
bu = lu = 0;
- res = &bridge->resource[PCI_BRIDGE_RESOURCES + 2];
+ res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
pcibios_resource_to_bus(bridge->bus, &region, res);
if (res->flags & IORESOURCE_PREFETCH) {
l = (region.start >> 16) & 0xfff0;
@@ -707,14 +707,14 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
if (!pci_bus_clip_resource(bridge, i))
return -EINVAL; /* Clipping didn't change anything */
- switch (i - PCI_BRIDGE_RESOURCES) {
- case 0:
+ switch (i) {
+ case PCI_BRIDGE_IO_WINDOW:
pci_setup_bridge_io(bridge);
break;
- case 1:
+ case PCI_BRIDGE_MEM_WINDOW:
pci_setup_bridge_mmio(bridge);
break;
- case 2:
+ case PCI_BRIDGE_PREF_MEM_WINDOW:
pci_setup_bridge_mmio_pref(bridge);
break;
default:
@@ -735,18 +735,22 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
static void pci_bridge_check_ranges(struct pci_bus *bus)
{
struct pci_dev *bridge = bus->self;
- struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
+ struct resource *b_res;
- b_res[1].flags |= IORESOURCE_MEM;
+ b_res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW];
+ b_res->flags |= IORESOURCE_MEM;
- if (bridge->io_window)
- b_res[0].flags |= IORESOURCE_IO;
+ if (bridge->io_window) {
+ b_res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
+ b_res->flags |= IORESOURCE_IO;
+ }
if (bridge->pref_window) {
- b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ b_res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
+ b_res->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
if (bridge->pref_64_window) {
- b_res[2].flags |= IORESOURCE_MEM_64;
- b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
+ b_res->flags |= IORESOURCE_MEM_64 |
+ PCI_PREF_RANGE_TYPE_64;
}
}
}
@@ -1105,35 +1109,37 @@ static void pci_bus_size_cardbus(struct pci_bus *bus,
struct list_head *realloc_head)
{
struct pci_dev *bridge = bus->self;
- struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
+ struct resource *b_res;
resource_size_t b_res_3_size = pci_cardbus_mem_size * 2;
u16 ctrl;
- if (b_res[0].parent)
+ b_res = &bridge->resource[PCI_CB_BRIDGE_IO_0_WINDOW];
+ if (b_res->parent)
goto handle_b_res_1;
/*
* Reserve some resources for CardBus. We reserve a fixed amount
* of bus space for CardBus bridges.
*/
- b_res[0].start = pci_cardbus_io_size;
- b_res[0].end = b_res[0].start + pci_cardbus_io_size - 1;
- b_res[0].flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN;
+ b_res->start = pci_cardbus_io_size;
+ b_res->end = b_res->start + pci_cardbus_io_size - 1;
+ b_res->flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN;
if (realloc_head) {
- b_res[0].end -= pci_cardbus_io_size;
+ b_res->end -= pci_cardbus_io_size;
add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size,
- pci_cardbus_io_size);
+ pci_cardbus_io_size);
}
handle_b_res_1:
- if (b_res[1].parent)
+ b_res = &bridge->resource[PCI_CB_BRIDGE_IO_1_WINDOW];
+ if (b_res->parent)
goto handle_b_res_2;
- b_res[1].start = pci_cardbus_io_size;
- b_res[1].end = b_res[1].start + pci_cardbus_io_size - 1;
- b_res[1].flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN;
+ b_res->start = pci_cardbus_io_size;
+ b_res->end = b_res->start + pci_cardbus_io_size - 1;
+ b_res->flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN;
if (realloc_head) {
- b_res[1].end -= pci_cardbus_io_size;
- add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size,
- pci_cardbus_io_size);
+ b_res->end -= pci_cardbus_io_size;
+ add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size,
+ pci_cardbus_io_size);
}
handle_b_res_2:
@@ -1153,21 +1159,22 @@ handle_b_res_2:
pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
}
- if (b_res[2].parent)
+ b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_0_WINDOW];
+ if (b_res->parent)
goto handle_b_res_3;
/*
* If we have prefetchable memory support, allocate two regions.
* Otherwise, allocate one region of twice the size.
*/
if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
- b_res[2].start = pci_cardbus_mem_size;
- b_res[2].end = b_res[2].start + pci_cardbus_mem_size - 1;
- b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH |
- IORESOURCE_STARTALIGN;
+ b_res->start = pci_cardbus_mem_size;
+ b_res->end = b_res->start + pci_cardbus_mem_size - 1;
+ b_res->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH |
+ IORESOURCE_STARTALIGN;
if (realloc_head) {
- b_res[2].end -= pci_cardbus_mem_size;
- add_to_list(realloc_head, bridge, b_res+2,
- pci_cardbus_mem_size, pci_cardbus_mem_size);
+ b_res->end -= pci_cardbus_mem_size;
+ add_to_list(realloc_head, bridge, b_res,
+ pci_cardbus_mem_size, pci_cardbus_mem_size);
}
/* Reduce that to half */
@@ -1175,15 +1182,16 @@ handle_b_res_2:
}
handle_b_res_3:
- if (b_res[3].parent)
+ b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_1_WINDOW];
+ if (b_res->parent)
goto handle_done;
- b_res[3].start = pci_cardbus_mem_size;
- b_res[3].end = b_res[3].start + b_res_3_size - 1;
- b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_STARTALIGN;
+ b_res->start = pci_cardbus_mem_size;
+ b_res->end = b_res->start + b_res_3_size - 1;
+ b_res->flags |= IORESOURCE_MEM | IORESOURCE_STARTALIGN;
if (realloc_head) {
- b_res[3].end -= b_res_3_size;
- add_to_list(realloc_head, bridge, b_res+3, b_res_3_size,
- pci_cardbus_mem_size);
+ b_res->end -= b_res_3_size;
+ add_to_list(realloc_head, bridge, b_res, b_res_3_size,
+ pci_cardbus_mem_size);
}
handle_done:
@@ -1227,7 +1235,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
break;
hdr_type = -1; /* Intentionally invalid - not a PCI device. */
} else {
- pref = &bus->self->resource[PCI_BRIDGE_RESOURCES + 2];
+ pref = &bus->self->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
hdr_type = bus->self->hdr_type;
}
@@ -1885,9 +1893,9 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
struct pci_dev *dev, *bridge = bus->self;
resource_size_t io_per_hp, mmio_per_hp, mmio_pref_per_hp, align;
- io_res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
- mmio_res = &bridge->resource[PCI_BRIDGE_RESOURCES + 1];
- mmio_pref_res = &bridge->resource[PCI_BRIDGE_RESOURCES + 2];
+ io_res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
+ mmio_res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW];
+ mmio_pref_res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
/*
* The alignment of this bridge is yet to be considered, hence it must
@@ -1960,21 +1968,21 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
* Reduce the available resource space by what the
* bridge and devices below it occupy.
*/
- res = &dev->resource[PCI_BRIDGE_RESOURCES + 0];
+ res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
align = pci_resource_alignment(dev, res);
align = align ? ALIGN(io.start, align) - io.start : 0;
used_size = align + resource_size(res);
if (!res->parent)
io.start = min(io.start + used_size, io.end + 1);
- res = &dev->resource[PCI_BRIDGE_RESOURCES + 1];
+ res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
align = pci_resource_alignment(dev, res);
align = align ? ALIGN(mmio.start, align) - mmio.start : 0;
used_size = align + resource_size(res);
if (!res->parent)
mmio.start = min(mmio.start + used_size, mmio.end + 1);
- res = &dev->resource[PCI_BRIDGE_RESOURCES + 2];
+ res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
align = pci_resource_alignment(dev, res);
align = align ? ALIGN(mmio_pref.start, align) -
mmio_pref.start : 0;
@@ -2027,9 +2035,9 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge,
return;
/* Take the initial extra resources from the hotplug port */
- available_io = bridge->resource[PCI_BRIDGE_RESOURCES + 0];
- available_mmio = bridge->resource[PCI_BRIDGE_RESOURCES + 1];
- available_mmio_pref = bridge->resource[PCI_BRIDGE_RESOURCES + 2];
+ available_io = bridge->resource[PCI_BRIDGE_IO_WINDOW];
+ available_mmio = bridge->resource[PCI_BRIDGE_MEM_WINDOW];
+ available_mmio_pref = bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
pci_bus_distribute_available_resources(bridge->subordinate,
add_list, available_io,
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index d8ca40a97693..d21fa04fa44d 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -439,10 +439,11 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size)
res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
/* Check if the new config works by trying to assign everything. */
- ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
- if (ret)
- goto error_resize;
-
+ if (dev->bus->self) {
+ ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
+ if (ret)
+ goto error_resize;
+ }
return 0;
error_resize:
diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index e69cac84b605..850cfeb74608 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -25,7 +25,7 @@ static int max_devices = 16;
module_param(max_devices, int, 0644);
MODULE_PARM_DESC(max_devices, "max number of switchtec device instances");
-static bool use_dma_mrpc = 1;
+static bool use_dma_mrpc = true;
module_param(use_dma_mrpc, bool, 0644);
MODULE_PARM_DESC(use_dma_mrpc,
"Enable the use of the DMA MRPC feature");