diff --git a/drivers/pci/controller/pci-msm.c b/drivers/pci/controller/pci-msm.c index 7be12a223301..8e149cf06896 100644 --- a/drivers/pci/controller/pci-msm.c +++ b/drivers/pci/controller/pci-msm.c @@ -851,6 +851,9 @@ struct msm_pcie_dev_t { bool drv_supported; void (*rumi_init)(struct msm_pcie_dev_t *pcie_dev); + + u32 *filtered_bdfs; + u32 bdf_count; }; struct msm_root_dev_t { @@ -3004,7 +3007,7 @@ static int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper, struct msm_pcie_dev_t *dev; void __iomem *config_base; bool rc = false; - u32 rc_idx; + u32 rc_idx, *filtered_bdf; int rv = 0; u32 bdf = BDF_OFFSET(bus->number, devfn); int i; @@ -3060,6 +3063,19 @@ static int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper, goto unlock; } + /* 32-bit BDF filtering */ + if (dev->bdf_count) { + i = dev->bdf_count; + filtered_bdf = dev->filtered_bdfs; + while (i--) { + if (*filtered_bdf == bdf) { + *val = ~0; + goto unlock; + } + filtered_bdf++; + } + } + if (!rc && !dev->enumerated) msm_pcie_cfg_bdf(dev, bus->number, devfn); @@ -5932,7 +5948,7 @@ static int msm_pcie_probe(struct platform_device *pdev) { int ret = 0; int rc_idx = -1; - int i, j; + int i, j, size; struct msm_pcie_dev_t *pcie_dev; struct device_node *of_node; @@ -6244,6 +6260,23 @@ static int msm_pcie_probe(struct platform_device *pdev) pcie_dev->drv_ready = true; + of_get_property(pdev->dev.of_node, "qcom,filtered-bdfs", &size); + if (size) { + pcie_dev->filtered_bdfs = devm_kzalloc(&pdev->dev, size, + GFP_KERNEL); + if (!pcie_dev->filtered_bdfs) + return -ENOMEM; + + pcie_dev->bdf_count = size / sizeof(*pcie_dev->filtered_bdfs); + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,filtered-bdfs", + pcie_dev->filtered_bdfs, + pcie_dev->bdf_count); + if (ret) + pcie_dev->bdf_count = 0; + } + if (pcie_dev->boot_option & MSM_PCIE_NO_PROBE_ENUMERATION) { PCIE_DBG(pcie_dev, "PCIe: RC%d will be enumerated by client or endpoint.\n",