QM_VF_IRQ_NUM_CAP,
 };
 
+enum qm_pre_store_cap_idx {
+       QM_EQ_IRQ_TYPE_CAP_IDX = 0x0,
+       QM_AEQ_IRQ_TYPE_CAP_IDX,
+       QM_ABN_IRQ_TYPE_CAP_IDX,
+       QM_PF2VF_IRQ_TYPE_CAP_IDX,
+};
+
 static const struct hisi_qm_cap_info qm_cap_info_comm[] = {
        {QM_SUPPORT_DB_ISOLATION, 0x30,   0, BIT(0),  0x0, 0x0, 0x0},
        {QM_SUPPORT_FUNC_QOS,     0x3100, 0, BIT(8),  0x0, 0x0, 0x1},
        {QM_VF_IRQ_NUM_CAP,     0x311c,   0,  GENMASK(15, 0), 0x1,       0x2,       0x3},
 };
 
+static const u32 qm_pre_store_caps[] = {
+       QM_EQ_IRQ_TYPE_CAP,
+       QM_AEQ_IRQ_TYPE_CAP,
+       QM_ABN_IRQ_TYPE_CAP,
+       QM_PF2VF_IRQ_TYPE_CAP,
+};
+
 struct qm_mailbox {
        __le16 w0;
        __le16 queue_num;
        if (qm->fun_type == QM_HW_VF)
                return;
 
-       val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver);
+       val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val;
        if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK))
                return;
 
        if (qm->fun_type == QM_HW_VF)
                return 0;
 
-       val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver);
+       val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val;
        if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK))
                return 0;
 
        struct pci_dev *pdev = qm->pdev;
        u32 irq_vector, val;
 
-       val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver);
+       val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val;
        if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
                return;
 
        u32 irq_vector, val;
        int ret;
 
-       val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver);
+       val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val;
        if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
                return 0;
 
        struct pci_dev *pdev = qm->pdev;
        u32 irq_vector, val;
 
-       val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver);
+       val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val;
        if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
                return;
 
        u32 irq_vector, val;
        int ret;
 
-       val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver);
+       val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val;
        if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
                return 0;
 
        struct pci_dev *pdev = qm->pdev;
        u32 irq_vector, val;
 
-       val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver);
+       val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val;
        if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
                return;
 
        u32 irq_vector, val;
        int ret;
 
-       val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver);
+       val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val;
        if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
                return 0;
 
        return 0;
 }
 
-static void qm_get_hw_caps(struct hisi_qm *qm)
+static int qm_pre_store_irq_type_caps(struct hisi_qm *qm)
+{
+       struct hisi_qm_cap_record *qm_cap;
+       struct pci_dev *pdev = qm->pdev;
+       size_t i, size;
+
+       size = ARRAY_SIZE(qm_pre_store_caps);
+       qm_cap = devm_kzalloc(&pdev->dev, sizeof(*qm_cap) * size, GFP_KERNEL);
+       if (!qm_cap)
+               return -ENOMEM;
+
+       for (i = 0; i < size; i++) {
+               qm_cap[i].type = qm_pre_store_caps[i];
+               qm_cap[i].cap_val = hisi_qm_get_hw_info(qm, qm_basic_info,
+                                                       qm_pre_store_caps[i], qm->cap_ver);
+       }
+
+       qm->cap_tables.qm_cap_table = qm_cap;
+
+       return 0;
+}
+
+static int qm_get_hw_caps(struct hisi_qm *qm)
 {
        const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ?
                                                  qm_cap_info_pf : qm_cap_info_vf;
                if (val)
                        set_bit(cap_info[i].type, &qm->caps);
        }
+
+       /* Fetch and save the value of irq type related capability registers */
+       return qm_pre_store_irq_type_caps(qm);
 }
 
 static int qm_get_pci_res(struct hisi_qm *qm)
                goto err_request_mem_regions;
        }
 
-       qm_get_hw_caps(qm);
+       ret = qm_get_hw_caps(qm);
+       if (ret)
+               goto err_ioremap;
+
        if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) {
                qm->db_interval = QM_QP_DB_INTERVAL;
                qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4);