Introduce a callback for outbound ATU range checking to support range validations specific to cases that deviate from the generic check. Signed-off-by: Randolph Lin <randolph@xxxxxxxxxxxxx> --- drivers/pci/controller/dwc/pcie-designware.c | 18 +++++++++++++----- drivers/pci/controller/dwc/pcie-designware.h | 3 +++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 89aad5a08928..f410aefaeb5e 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -535,12 +535,20 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u32 retries, val; u64 limit_addr; - limit_addr = parent_bus_addr + atu->size - 1; + if (pci->ops && pci->ops->outbound_atu_check) { + val = pci->ops->outbound_atu_check(pci, atu, &limit_addr); + if (val) + return val; + } else { + limit_addr = parent_bus_addr + atu->size - 1; - if ((limit_addr & ~pci->region_limit) != (parent_bus_addr & ~pci->region_limit) || - !IS_ALIGNED(parent_bus_addr, pci->region_align) || - !IS_ALIGNED(atu->pci_addr, pci->region_align) || !atu->size) { - return -EINVAL; + if ((limit_addr & ~pci->region_limit) != + (parent_bus_addr & ~pci->region_limit) || + !IS_ALIGNED(parent_bus_addr, pci->region_align) || + !IS_ALIGNED(atu->pci_addr, pci->region_align) || + !atu->size) { + return -EINVAL; + } } dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_LOWER_BASE, diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 00f52d472dcd..40dd2c83b1c7 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -469,6 +469,9 @@ struct dw_pcie_ep { struct dw_pcie_ops { u64 (*cpu_addr_fixup)(struct dw_pcie *pcie, u64 cpu_addr); + u32 (*outbound_atu_check)(struct dw_pcie *pcie, + const struct dw_pcie_ob_atu_cfg *atu, + u64 *limit_addr); u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, size_t size); void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, -- 2.34.1