[PATCH 2/6] PCI: dwc: Add outbound ATU range check callback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux