}
 
 const struct pci_ecam_ops al_pcie_ops = {
-       .bus_shift    = 20,
        .init         =  al_pcie_init,
        .pci_ops      = {
                .map_bus    = al_pcie_map_bus,
        struct al_pcie_target_bus_cfg target_bus_cfg;
 };
 
-#define PCIE_ECAM_DEVFN(x)             (((x) & 0xff) << 12)
-
 #define to_al_pcie(x)          dev_get_drvdata((x)->dev)
 
 static inline u32 al_pcie_controller_readl(struct al_pcie *pcie, u32 offset)
        struct al_pcie_target_bus_cfg *target_bus_cfg = &pcie->target_bus_cfg;
        unsigned int busnr_ecam = busnr & target_bus_cfg->ecam_mask;
        unsigned int busnr_reg = busnr & target_bus_cfg->reg_mask;
-       void __iomem *pci_base_addr;
-
-       pci_base_addr = (void __iomem *)((uintptr_t)pp->va_cfg0_base +
-                                        (busnr_ecam << 20) +
-                                        PCIE_ECAM_DEVFN(devfn));
 
        if (busnr_reg != target_bus_cfg->reg_val) {
                dev_dbg(pcie->pci->dev, "Changing target bus busnum val from 0x%x to 0x%x\n",
                                       target_bus_cfg->reg_mask);
        }
 
-       return pci_base_addr + where;
+       return pp->va_cfg0_base + PCIE_ECAM_OFFSET(busnr_ecam, devfn, where);
 }
 
 static struct pci_ops al_child_pci_ops = {
 
        target_bus_cfg = &pcie->target_bus_cfg;
 
-       ecam_bus_mask = (pcie->ecam_size >> 20) - 1;
+       ecam_bus_mask = (pcie->ecam_size >> PCIE_ECAM_BUS_SHIFT) - 1;
        if (ecam_bus_mask > 255) {
                dev_warn(pcie->dev, "ECAM window size is larger than 256MB. Cutting off at 256\n");
                ecam_bus_mask = 255;
 
 }
 
 const struct pci_ecam_ops hisi_pcie_ops = {
-       .bus_shift    = 20,
        .init         =  hisi_pcie_init,
        .pci_ops      = {
                .map_bus    = hisi_pcie_map_bus,
 }
 
 static const struct pci_ecam_ops hisi_pcie_platform_ops = {
-       .bus_shift    = 20,
        .init         =  hisi_pcie_platform_init,
        .pci_ops      = {
                .map_bus    = hisi_pcie_map_bus,
 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/pci-ecam.h>
 #include <linux/init.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #define PCIE_CONFIG_WR_TYPE0                   0xa
 #define PCIE_CONFIG_WR_TYPE1                   0xb
 
-#define PCIE_CONF_BUS(bus)                     (((bus) & 0xff) << 20)
-#define PCIE_CONF_DEV(dev)                     (((dev) & 0x1f) << 15)
-#define PCIE_CONF_FUNC(fun)                    (((fun) & 0x7)  << 12)
-#define PCIE_CONF_REG(reg)                     ((reg) & 0xffc)
-#define PCIE_CONF_ADDR(bus, devfn, where)      \
-       (PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn))    | \
-        PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where))
-
 #define PIO_RETRY_CNT                  500
 #define PIO_RETRY_DELAY                        2 /* 2 us*/
 
        advk_writel(pcie, reg, PIO_CTRL);
 
        /* Program the address registers */
-       reg = PCIE_CONF_ADDR(bus->number, devfn, where);
+       reg = ALIGN_DOWN(PCIE_ECAM_OFFSET(bus->number, devfn, where), 4);
        advk_writel(pcie, reg, PIO_ADDR_LS);
        advk_writel(pcie, 0, PIO_ADDR_MS);
 
        advk_writel(pcie, reg, PIO_CTRL);
 
        /* Program the address registers */
-       reg = PCIE_CONF_ADDR(bus->number, devfn, where);
+       reg = ALIGN_DOWN(PCIE_ECAM_OFFSET(bus->number, devfn, where), 4);
        advk_writel(pcie, reg, PIO_ADDR_LS);
        advk_writel(pcie, 0, PIO_ADDR_MS);
 
 
 }
 
 static const struct pci_ecam_ops pci_dw_ecam_bus_ops = {
-       .bus_shift      = 20,
        .pci_ops        = {
                .map_bus        = pci_dw_ecam_map_bus,
                .read           = pci_generic_config_read,
 
 }
 
 const struct pci_ecam_ops pci_thunder_ecam_ops = {
-       .bus_shift      = 20,
        .pci_ops        = {
                .map_bus        = pci_ecam_map_bus,
                .read           = thunder_ecam_config_read,
 
 #include <linux/of_pci.h>
 #include <linux/of_platform.h>
 #include <linux/pci.h>
+#include <linux/pci-ecam.h>
 #include <linux/printk.h>
 #include <linux/reset.h>
 #include <linux/sizes.h>
 #define  MSI_INT_MASK_CLR              0x14
 
 #define PCIE_EXT_CFG_DATA                              0x8000
-
 #define PCIE_EXT_CFG_INDEX                             0x9000
-#define  PCIE_EXT_BUSNUM_SHIFT                         20
-#define  PCIE_EXT_SLOT_SHIFT                           15
-#define  PCIE_EXT_FUNC_SHIFT                           12
 
 #define  PCIE_RGR1_SW_INIT_1_PERST_MASK                        0x1
 #define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT               0x0
        return dla && plu;
 }
 
-/* Configuration space read/write support */
-static inline int brcm_pcie_cfg_index(int busnr, int devfn, int reg)
-{
-       return ((PCI_SLOT(devfn) & 0x1f) << PCIE_EXT_SLOT_SHIFT)
-               | ((PCI_FUNC(devfn) & 0x07) << PCIE_EXT_FUNC_SHIFT)
-               | (busnr << PCIE_EXT_BUSNUM_SHIFT)
-               | (reg & ~3);
-}
-
 static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
                                        int where)
 {
                return PCI_SLOT(devfn) ? NULL : base + where;
 
        /* For devices, write to the config space index register */
-       idx = brcm_pcie_cfg_index(bus->number, devfn, 0);
+       idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
        writel(idx, pcie->base + PCIE_EXT_CFG_INDEX);
        return base + PCIE_EXT_CFG_DATA + where;
 }
 
                                       struct pci_bus *bus, u32 devfn,
                                       int where, int size, u32 *val)
 {
-       u32 busdev;
+       void __iomem *addr;
 
-       busdev = PCIE_ECAM_ADDR(bus->number, PCI_SLOT(devfn),
-                               PCI_FUNC(devfn), where);
+       addr = rockchip->reg_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
 
-       if (!IS_ALIGNED(busdev, size)) {
+       if (!IS_ALIGNED((uintptr_t)addr, size)) {
                *val = 0;
                return PCIBIOS_BAD_REGISTER_NUMBER;
        }
                                                AXI_WRAPPER_TYPE1_CFG);
 
        if (size == 4) {
-               *val = readl(rockchip->reg_base + busdev);
+               *val = readl(addr);
        } else if (size == 2) {
-               *val = readw(rockchip->reg_base + busdev);
+               *val = readw(addr);
        } else if (size == 1) {
-               *val = readb(rockchip->reg_base + busdev);
+               *val = readb(addr);
        } else {
                *val = 0;
                return PCIBIOS_BAD_REGISTER_NUMBER;
                                       struct pci_bus *bus, u32 devfn,
                                       int where, int size, u32 val)
 {
-       u32 busdev;
+       void __iomem *addr;
 
-       busdev = PCIE_ECAM_ADDR(bus->number, PCI_SLOT(devfn),
-                               PCI_FUNC(devfn), where);
-       if (!IS_ALIGNED(busdev, size))
+       addr = rockchip->reg_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
+
+       if (!IS_ALIGNED((uintptr_t)addr, size))
                return PCIBIOS_BAD_REGISTER_NUMBER;
 
        if (pci_is_root_bus(bus->parent))
                                                AXI_WRAPPER_TYPE1_CFG);
 
        if (size == 4)
-               writel(val, rockchip->reg_base + busdev);
+               writel(val, addr);
        else if (size == 2)
-               writew(val, rockchip->reg_base + busdev);
+               writew(val, addr);
        else if (size == 1)
-               writeb(val, rockchip->reg_base + busdev);
+               writeb(val, addr);
        else
                return PCIBIOS_BAD_REGISTER_NUMBER;
 
 
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/pci-ecam.h>
 
 /*
  * The upper 16 bits of PCIE_CLIENT_CONFIG are a write mask for the lower 16
 #define MIN_AXI_ADDR_BITS_PASSED               8
 #define PCIE_RC_SEND_PME_OFF                   0x11960
 #define ROCKCHIP_VENDOR_ID                     0x1d87
-#define PCIE_ECAM_BUS(x)                       (((x) & 0xff) << 20)
-#define PCIE_ECAM_DEV(x)                       (((x) & 0x1f) << 15)
-#define PCIE_ECAM_FUNC(x)                      (((x) & 0x7) << 12)
-#define PCIE_ECAM_REG(x)                       (((x) & 0xfff) << 0)
-#define PCIE_ECAM_ADDR(bus, dev, func, reg) \
-         (PCIE_ECAM_BUS(bus) | PCIE_ECAM_DEV(dev) | \
-          PCIE_ECAM_FUNC(func) | PCIE_ECAM_REG(reg))
 #define PCIE_LINK_IS_L2(x) \
        (((x) & PCIE_CLIENT_DEBUG_LTSSM_MASK) == PCIE_CLIENT_DEBUG_LTSSM_L2)
 #define PCIE_LINK_UP(x) \
 
 }
 
 static const struct pci_ecam_ops smp8759_ecam_ops = {
-       .bus_shift      = 20,
        .pci_ops        = {
                .map_bus        = pci_ecam_map_bus,
                .read           = smp8759_config_read,
 
 #include <linux/of_platform.h>
 #include <linux/of_irq.h>
 #include <linux/pci.h>
+#include <linux/pci-ecam.h>
 #include <linux/platform_device.h>
 #include <linux/irqchip/chained_irq.h>
 
 #define E_ECAM_CR_ENABLE               BIT(0)
 #define E_ECAM_SIZE_LOC                        GENMASK(20, 16)
 #define E_ECAM_SIZE_SHIFT              16
-#define ECAM_BUS_LOC_SHIFT             20
-#define ECAM_DEV_LOC_SHIFT             12
 #define NWL_ECAM_VALUE_DEFAULT         12
 
 #define CFG_DMA_REG_BAR                        GENMASK(2, 0)
                                      int where)
 {
        struct nwl_pcie *pcie = bus->sysdata;
-       int relbus;
 
        if (!nwl_pcie_valid_device(bus, devfn))
                return NULL;
 
-       relbus = (bus->number << ECAM_BUS_LOC_SHIFT) |
-                       (devfn << ECAM_DEV_LOC_SHIFT);
-
-       return pcie->ecam_base + relbus + where;
+       return pcie->ecam_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
 }
 
 /* PCIe operations */
 
 #include <linux/of_platform.h>
 #include <linux/of_irq.h>
 #include <linux/pci.h>
+#include <linux/pci-ecam.h>
 #include <linux/platform_device.h>
 
 #include "../pci.h"
 /* Phy Status/Control Register definitions */
 #define XILINX_PCIE_REG_PSCR_LNKUP     BIT(11)
 
-/* ECAM definitions */
-#define ECAM_BUS_NUM_SHIFT             20
-#define ECAM_DEV_NUM_SHIFT             12
-
 /* Number of MSI IRQs */
 #define XILINX_NUM_MSI_IRQS            128
 
                                         unsigned int devfn, int where)
 {
        struct xilinx_pcie_port *port = bus->sysdata;
-       int relbus;
 
        if (!xilinx_pcie_valid_device(bus, devfn))
                return NULL;
 
-       relbus = (bus->number << ECAM_BUS_NUM_SHIFT) |
-                (devfn << ECAM_DEV_NUM_SHIFT);
-
-       return port->reg_base + relbus + where;
+       return port->reg_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
 }
 
 /* PCIe operations */
 
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/pci.h>
+#include <linux/pci-ecam.h>
 #include <linux/srcu.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
 static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus,
                                  unsigned int devfn, int reg, int len)
 {
-       char __iomem *addr = vmd->cfgbar +
-                            ((bus->number - vmd->busn_start) << 20) +
-                            (devfn << 12) + reg;
+       unsigned int busnr_ecam = bus->number - vmd->busn_start;
+       u32 offset = PCIE_ECAM_OFFSET(busnr_ecam, devfn, reg);
 
-       if ((addr - vmd->cfgbar) + len >=
-           resource_size(&vmd->dev->resource[VMD_CFGBAR]))
+       if (offset + len >= resource_size(&vmd->dev->resource[VMD_CFGBAR]))
                return NULL;
 
-       return addr;
+       return vmd->cfgbar + offset;
 }
 
 /*
 
                struct resource *cfgres, struct resource *busr,
                const struct pci_ecam_ops *ops)
 {
+       unsigned int bus_shift = ops->bus_shift;
        struct pci_config_window *cfg;
        unsigned int bus_range, bus_range_max, bsz;
        struct resource *conflict;
        if (!cfg)
                return ERR_PTR(-ENOMEM);
 
+       /* ECAM-compliant platforms need not supply ops->bus_shift */
+       if (!bus_shift)
+               bus_shift = PCIE_ECAM_BUS_SHIFT;
+
        cfg->parent = dev;
        cfg->ops = ops;
        cfg->busr.start = busr->start;
        cfg->busr.end = busr->end;
        cfg->busr.flags = IORESOURCE_BUS;
        bus_range = resource_size(&cfg->busr);
-       bus_range_max = resource_size(cfgres) >> ops->bus_shift;
+       bus_range_max = resource_size(cfgres) >> bus_shift;
        if (bus_range > bus_range_max) {
                bus_range = bus_range_max;
                cfg->busr.end = busr->start + bus_range - 1;
                dev_warn(dev, "ECAM area %pR can only accommodate %pR (reduced from %pR desired)\n",
                         cfgres, &cfg->busr, busr);
        }
-       bsz = 1 << ops->bus_shift;
+       bsz = 1 << bus_shift;
 
        cfg->res.start = cfgres->start;
        cfg->res.end = cfgres->end;
                               int where)
 {
        struct pci_config_window *cfg = bus->sysdata;
+       unsigned int bus_shift = cfg->ops->bus_shift;
        unsigned int devfn_shift = cfg->ops->bus_shift - 8;
        unsigned int busn = bus->number;
        void __iomem *base;
+       u32 bus_offset, devfn_offset;
 
        if (busn < cfg->busr.start || busn > cfg->busr.end)
                return NULL;
 
        busn -= cfg->busr.start;
-       if (per_bus_mapping)
+       if (per_bus_mapping) {
                base = cfg->winp[busn];
-       else
-               base = cfg->win + (busn << cfg->ops->bus_shift);
-       return base + (devfn << devfn_shift) + where;
+               busn = 0;
+       } else
+               base = cfg->win;
+
+       if (cfg->ops->bus_shift) {
+               bus_offset = (busn & PCIE_ECAM_BUS_MASK) << bus_shift;
+               devfn_offset = (devfn & PCIE_ECAM_DEVFN_MASK) << devfn_shift;
+               where &= PCIE_ECAM_REG_MASK;
+
+               return base + (bus_offset | devfn_offset | where);
+       }
+
+       return base + PCIE_ECAM_OFFSET(busn, devfn, where);
 }
 EXPORT_SYMBOL_GPL(pci_ecam_map_bus);
 
 /* ECAM ops */
 const struct pci_ecam_ops pci_generic_ecam_ops = {
-       .bus_shift      = 20,
        .pci_ops        = {
                .map_bus        = pci_ecam_map_bus,
                .read           = pci_generic_config_read,
 #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
 /* ECAM ops for 32-bit access only (non-compliant) */
 const struct pci_ecam_ops pci_32b_ops = {
-       .bus_shift      = 20,
        .pci_ops        = {
                .map_bus        = pci_ecam_map_bus,
                .read           = pci_generic_config_read32,
 
 /* ECAM ops for 32-bit read only (non-compliant) */
 const struct pci_ecam_ops pci_32b_read_ops = {
-       .bus_shift      = 20,
        .pci_ops        = {
                .map_bus        = pci_ecam_map_bus,
                .read           = pci_generic_config_read32,
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 
+/*
+ * Memory address shift values for the byte-level address that
+ * can be used when accessing the PCI Express Configuration Space.
+ */
+
+/*
+ * Enhanced Configuration Access Mechanism (ECAM)
+ *
+ * See PCI Express Base Specification, Revision 5.0, Version 1.0,
+ * Section 7.2.2, Table 7-1, p. 677.
+ */
+#define PCIE_ECAM_BUS_SHIFT    20 /* Bus number */
+#define PCIE_ECAM_DEVFN_SHIFT  12 /* Device and Function number */
+
+#define PCIE_ECAM_BUS_MASK     0xff
+#define PCIE_ECAM_DEVFN_MASK   0xff
+#define PCIE_ECAM_REG_MASK     0xfff /* Limit offset to a maximum of 4K */
+
+#define PCIE_ECAM_BUS(x)       (((x) & PCIE_ECAM_BUS_MASK) << PCIE_ECAM_BUS_SHIFT)
+#define PCIE_ECAM_DEVFN(x)     (((x) & PCIE_ECAM_DEVFN_MASK) << PCIE_ECAM_DEVFN_SHIFT)
+#define PCIE_ECAM_REG(x)       ((x) & PCIE_ECAM_REG_MASK)
+
+#define PCIE_ECAM_OFFSET(bus, devfn, where) \
+       (PCIE_ECAM_BUS(bus) | \
+        PCIE_ECAM_DEVFN(devfn) | \
+        PCIE_ECAM_REG(where))
+
 /*
  * struct to hold pci ops and bus shift of the config window
  * for a PCI controller.