summaryrefslogtreecommitdiff
path: root/drivers/pci/controller
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2026-10-21 13:20:35 -0500
committerBjorn Helgaas <bhelgaas@google.com>2026-10-21 13:20:35 -0500
commita26ee237c910afa122e3338b78aa6bfac1b76972 (patch)
treefffd821cec4313b3306936d40075a7e9475791a0 /drivers/pci/controller
parent6f683ae8ae7374d71fe9435bc31fb018bbedae3e (diff)
parent9850907ee1dd4376c09c4129e0adbe3b39d191b7 (diff)
Merge branch 'pci/controller/iproc-bcma'
- Expose devm_pci_alloc_host_bridge_release() so drivers can share a devm release function even if they don't need the device tree parsing done by devm_pci_alloc_host_bridge() (Bjorn Helgaas) - Request only the memory window from BCMA Enumeration ROM and warn if it doesn't match the one in DT (Semih Baskan) * pci/controller/iproc-bcma: PCI: iproc: Use the EROM outbound window on BCMA PCI: Expose devm_pci_alloc_host_bridge_release()
Diffstat (limited to 'drivers/pci/controller')
-rw-r--r--drivers/pci/controller/pcie-iproc-bcma.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/drivers/pci/controller/pcie-iproc-bcma.c b/drivers/pci/controller/pcie-iproc-bcma.c
index 593418c2bc3a..1e258cd8fed4 100644
--- a/drivers/pci/controller/pcie-iproc-bcma.c
+++ b/drivers/pci/controller/pcie-iproc-bcma.c
@@ -11,7 +11,9 @@
#include <linux/phy/phy.h>
#include <linux/bcma/bcma.h>
#include <linux/ioport.h>
+#include <linux/of_address.h>
+#include "../pci.h"
#include "pcie-iproc.h"
@@ -31,6 +33,29 @@ static int iproc_bcma_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return bcma_core_irq(bdev, 5);
}
+static void iproc_bcma_pcie_check_dt_window(struct iproc_pcie *pcie)
+{
+ struct device_node *np = pcie->dev->of_node;
+ struct of_pci_range_parser parser;
+ struct of_pci_range range;
+ struct resource res;
+
+ if (!np || of_pci_range_parser_init(&parser, np))
+ return;
+
+ for_each_of_pci_range(&parser, &range) {
+ if ((range.flags & IORESOURCE_TYPE_BITS) != IORESOURCE_MEM)
+ continue;
+
+ if (of_pci_range_to_resource(&range, np, &res))
+ continue;
+
+ if (res.start != pcie->mem.start || res.end != pcie->mem.end)
+ dev_warn(pcie->dev, "DT window %pR does not match EROM window %pR, using EROM\n",
+ &res, &pcie->mem);
+ }
+}
+
static int iproc_bcma_pcie_probe(struct bcma_device *bdev)
{
struct device *dev = &bdev->dev;
@@ -38,10 +63,20 @@ static int iproc_bcma_pcie_probe(struct bcma_device *bdev)
struct pci_host_bridge *bridge;
int ret;
- bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
+ bridge = pci_alloc_host_bridge(sizeof(*pcie));
if (!bridge)
return -ENOMEM;
+ bridge->dev.parent = dev;
+
+ ret = devm_add_action_or_reset(dev, devm_pci_alloc_host_bridge_release,
+ bridge);
+ if (ret)
+ return -ENOMEM;
+
+ bridge->swizzle_irq = pci_common_swizzle;
+ bridge->map_irq = iproc_bcma_pcie_map_irq;
+
pcie = pci_host_bridge_priv(bridge);
pcie->dev = dev;
@@ -59,13 +94,12 @@ static int iproc_bcma_pcie_probe(struct bcma_device *bdev)
pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1;
pcie->mem.name = "PCIe MEM space";
pcie->mem.flags = IORESOURCE_MEM;
+ iproc_bcma_pcie_check_dt_window(pcie);
pci_add_resource(&bridge->windows, &pcie->mem);
ret = devm_request_pci_bus_resources(dev, &bridge->windows);
if (ret)
return ret;
- bridge->map_irq = iproc_bcma_pcie_map_irq;
-
bcma_set_drvdata(bdev, pcie);
return iproc_pcie_setup(pcie, &bridge->windows);