int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
 {
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+       struct dw_pcie_ep_func *ep_func;
+       struct device *dev = pci->dev;
+       struct pci_epc *epc = ep->epc;
        unsigned int offset, ptm_cap_base;
        unsigned int nbars;
        u8 hdr_type;
+       u8 func_no;
+       int i, ret;
+       void *addr;
        u32 reg;
-       int i;
 
        hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) &
                   PCI_HEADER_TYPE_MASK;
                return -EIO;
        }
 
+       dw_pcie_version_detect(pci);
+
+       dw_pcie_iatu_detect(pci);
+
+       ret = dw_pcie_edma_detect(pci);
+       if (ret)
+               return ret;
+
+       if (!ep->ib_window_map) {
+               ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows,
+                                                      GFP_KERNEL);
+               if (!ep->ib_window_map)
+                       goto err_remove_edma;
+       }
+
+       if (!ep->ob_window_map) {
+               ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows,
+                                                      GFP_KERNEL);
+               if (!ep->ob_window_map)
+                       goto err_remove_edma;
+       }
+
+       if (!ep->outbound_addr) {
+               addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t),
+                                   GFP_KERNEL);
+               if (!addr)
+                       goto err_remove_edma;
+               ep->outbound_addr = addr;
+       }
+
+       for (func_no = 0; func_no < epc->max_functions; func_no++) {
+
+               ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
+               if (ep_func)
+                       continue;
+
+               ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL);
+               if (!ep_func)
+                       goto err_remove_edma;
+
+               ep_func->func_no = func_no;
+               ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no,
+                                                             PCI_CAP_ID_MSI);
+               ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no,
+                                                              PCI_CAP_ID_MSIX);
+
+               list_add_tail(&ep_func->list, &ep->func_list);
+       }
+
+       if (ep->ops->init)
+               ep->ops->init(ep);
+
        offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
        ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
 
        dw_pcie_dbi_ro_wr_dis(pci);
 
        return 0;
+
+err_remove_edma:
+       dw_pcie_edma_remove(pci);
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete);
 
 int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 {
        int ret;
-       void *addr;
-       u8 func_no;
        struct resource *res;
        struct pci_epc *epc;
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
        struct platform_device *pdev = to_platform_device(dev);
        struct device_node *np = dev->of_node;
        const struct pci_epc_features *epc_features;
-       struct dw_pcie_ep_func *ep_func;
 
        INIT_LIST_HEAD(&ep->func_list);
 
        if (ep->ops->pre_init)
                ep->ops->pre_init(ep);
 
-       dw_pcie_version_detect(pci);
-
-       dw_pcie_iatu_detect(pci);
-
-       ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows,
-                                              GFP_KERNEL);
-       if (!ep->ib_window_map)
-               return -ENOMEM;
-
-       ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows,
-                                              GFP_KERNEL);
-       if (!ep->ob_window_map)
-               return -ENOMEM;
-
-       addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t),
-                           GFP_KERNEL);
-       if (!addr)
-               return -ENOMEM;
-       ep->outbound_addr = addr;
-
        epc = devm_pci_epc_create(dev, &epc_ops);
        if (IS_ERR(epc)) {
                dev_err(dev, "Failed to create epc device\n");
        if (ret < 0)
                epc->max_functions = 1;
 
-       for (func_no = 0; func_no < epc->max_functions; func_no++) {
-               ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL);
-               if (!ep_func)
-                       return -ENOMEM;
-
-               ep_func->func_no = func_no;
-               ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no,
-                                                             PCI_CAP_ID_MSI);
-               ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no,
-                                                              PCI_CAP_ID_MSIX);
-
-               list_add_tail(&ep_func->list, &ep->func_list);
-       }
-
-       if (ep->ops->init)
-               ep->ops->init(ep);
-
        ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
                               ep->page_size);
        if (ret < 0) {
                goto err_exit_epc_mem;
        }
 
-       ret = dw_pcie_edma_detect(pci);
-       if (ret)
-               goto err_free_epc_mem;
-
        if (ep->ops->get_features) {
                epc_features = ep->ops->get_features(ep);
                if (epc_features->core_init_notifier)
                        return 0;
        }
 
+       /*
+        * NOTE:- Avoid accessing the hardware (Ex:- DBI space) before this
+        * step as platforms that implement 'core_init_notifier' feature may
+        * not have the hardware ready (i.e. core initialized) for access
+        * (Ex: tegra194). Any hardware access on such platforms result
+        * in system hang.
+        */
        ret = dw_pcie_ep_init_complete(ep);
        if (ret)
-               goto err_remove_edma;
+               goto err_free_epc_mem;
 
        return 0;
 
-err_remove_edma:
-       dw_pcie_edma_remove(pci);
-
 err_free_epc_mem:
        pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
                              epc->mem->window.page_size);