diff options
| author | Bjorn Helgaas <bhelgaas@google.com> | 2026-10-21 13:20:35 -0500 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2026-10-21 13:20:35 -0500 |
| commit | a26ee237c910afa122e3338b78aa6bfac1b76972 (patch) | |
| tree | fffd821cec4313b3306936d40075a7e9475791a0 /drivers/pci/controller | |
| parent | 6f683ae8ae7374d71fe9435bc31fb018bbedae3e (diff) | |
| parent | 9850907ee1dd4376c09c4129e0adbe3b39d191b7 (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.c | 40 |
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); |
