.stop_link = rockchip_pcie_stop_link,
 };
 
+static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
+{
+       struct rockchip_pcie *rockchip = arg;
+       struct dw_pcie *pci = &rockchip->pci;
+       struct dw_pcie_rp *pp = &pci->pp;
+       struct device *dev = pci->dev;
+       u32 reg, val;
+
+       reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
+       rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
+
+       dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
+       dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm(rockchip));
+
+       if (reg & PCIE_RDLH_LINK_UP_CHGED) {
+               val = rockchip_pcie_get_ltssm(rockchip);
+               if ((val & PCIE_LINKUP) == PCIE_LINKUP) {
+                       dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
+                       /* Rescan the bus to enumerate endpoint devices */
+                       pci_lock_rescan_remove();
+                       pci_rescan_bus(pp->bridge->bus);
+                       pci_unlock_rescan_remove();
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
 static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
 {
        struct rockchip_pcie *rockchip = arg;
        return IRQ_HANDLED;
 }
 
-static int rockchip_pcie_configure_rc(struct rockchip_pcie *rockchip)
+static int rockchip_pcie_configure_rc(struct platform_device *pdev,
+                                     struct rockchip_pcie *rockchip)
 {
+       struct device *dev = &pdev->dev;
        struct dw_pcie_rp *pp;
+       int irq, ret;
        u32 val;
 
        if (!IS_ENABLED(CONFIG_PCIE_ROCKCHIP_DW_HOST))
                return -ENODEV;
 
+       irq = platform_get_irq_byname(pdev, "sys");
+       if (irq < 0)
+               return irq;
+
+       ret = devm_request_threaded_irq(dev, irq, NULL,
+                                       rockchip_pcie_rc_sys_irq_thread,
+                                       IRQF_ONESHOT, "pcie-sys-rc", rockchip);
+       if (ret) {
+               dev_err(dev, "failed to request PCIe sys IRQ\n");
+               return ret;
+       }
+
        /* LTSSM enable control mode */
        val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE);
        rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
        pp = &rockchip->pci.pp;
        pp->ops = &rockchip_pcie_host_ops;
 
-       return dw_pcie_host_init(pp);
+       ret = dw_pcie_host_init(pp);
+       if (ret) {
+               dev_err(dev, "failed to initialize host\n");
+               return ret;
+       }
+
+       /* unmask DLL up/down indicator */
+       val = HIWORD_UPDATE(PCIE_RDLH_LINK_UP_CHGED, 0);
+       rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_MISC);
+
+       return ret;
 }
 
 static int rockchip_pcie_configure_ep(struct platform_device *pdev,
                return -ENODEV;
 
        irq = platform_get_irq_byname(pdev, "sys");
-       if (irq < 0) {
-               dev_err(dev, "missing sys IRQ resource\n");
+       if (irq < 0)
                return irq;
-       }
 
        ret = devm_request_threaded_irq(dev, irq, NULL,
                                        rockchip_pcie_ep_sys_irq_thread,
-                                       IRQF_ONESHOT, "pcie-sys", rockchip);
+                                       IRQF_ONESHOT, "pcie-sys-ep", rockchip);
        if (ret) {
                dev_err(dev, "failed to request PCIe sys IRQ\n");
                return ret;
        pci_epc_init_notify(rockchip->pci.ep.epc);
 
        /* unmask DLL up/down indicator and hot reset/link-down reset */
-       rockchip_pcie_writel_apb(rockchip, 0x60000, PCIE_CLIENT_INTR_MASK_MISC);
+       val = HIWORD_UPDATE(PCIE_RDLH_LINK_UP_CHGED | PCIE_LINK_REQ_RST_NOT_INT, 0);
+       rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_MISC);
 
        return ret;
 }
 
        switch (data->mode) {
        case DW_PCIE_RC_TYPE:
-               ret = rockchip_pcie_configure_rc(rockchip);
+               ret = rockchip_pcie_configure_rc(pdev, rockchip);
                if (ret)
                        goto deinit_clk;
                break;