return pcim_iomap_table(pcidev)[bar];
 }
 
+static int cci_pci_alloc_irq(struct pci_dev *pcidev)
+{
+       int ret, nvec = pci_msix_vec_count(pcidev);
+
+       if (nvec <= 0) {
+               dev_dbg(&pcidev->dev, "fpga interrupt not supported\n");
+               return 0;
+       }
+
+       ret = pci_alloc_irq_vectors(pcidev, nvec, nvec, PCI_IRQ_MSIX);
+       if (ret < 0)
+               return ret;
+
+       return nvec;
+}
+
+static void cci_pci_free_irq(struct pci_dev *pcidev)
+{
+       pci_free_irq_vectors(pcidev);
+}
+
 /* PCI Device ID */
 #define PCIE_DEVICE_ID_PF_INT_5_X      0xBCBD
 #define PCIE_DEVICE_ID_PF_INT_6_X      0xBCC0
 
        /* remove all children feature devices */
        dfl_fpga_feature_devs_remove(drvdata->cdev);
+       cci_pci_free_irq(pcidev);
+}
+
+static int *cci_pci_create_irq_table(struct pci_dev *pcidev, unsigned int nvec)
+{
+       unsigned int i;
+       int *table;
+
+       table = kcalloc(nvec, sizeof(int), GFP_KERNEL);
+       if (!table)
+               return table;
+
+       for (i = 0; i < nvec; i++)
+               table[i] = pci_irq_vector(pcidev, i);
+
+       return table;
 }
 
 /* enumerate feature devices under pci device */
 static int cci_enumerate_feature_devs(struct pci_dev *pcidev)
 {
        struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
+       int port_num, bar, i, nvec, ret = 0;
        struct dfl_fpga_enum_info *info;
        struct dfl_fpga_cdev *cdev;
        resource_size_t start, len;
-       int port_num, bar, i, ret = 0;
        void __iomem *base;
+       int *irq_table;
        u32 offset;
        u64 v;
 
        if (!info)
                return -ENOMEM;
 
+       /* add irq info for enumeration if the device support irq */
+       nvec = cci_pci_alloc_irq(pcidev);
+       if (nvec < 0) {
+               dev_err(&pcidev->dev, "Fail to alloc irq %d.\n", nvec);
+               ret = nvec;
+               goto enum_info_free_exit;
+       } else if (nvec) {
+               irq_table = cci_pci_create_irq_table(pcidev, nvec);
+               if (!irq_table) {
+                       ret = -ENOMEM;
+                       goto irq_free_exit;
+               }
+
+               ret = dfl_fpga_enum_info_add_irq(info, nvec, irq_table);
+               kfree(irq_table);
+               if (ret)
+                       goto irq_free_exit;
+       }
+
        /* start to find Device Feature List from Bar 0 */
        base = cci_pci_ioremap_bar(pcidev, 0);
        if (!base) {
                ret = -ENOMEM;
-               goto enum_info_free_exit;
+               goto irq_free_exit;
        }
 
        /*
                dfl_fpga_enum_info_add_dfl(info, start, len, base);
        } else {
                ret = -ENODEV;
-               goto enum_info_free_exit;
+               goto irq_free_exit;
        }
 
        /* start enumeration with prepared enumeration information */
        if (IS_ERR(cdev)) {
                dev_err(&pcidev->dev, "Enumeration failure\n");
                ret = PTR_ERR(cdev);
-               goto enum_info_free_exit;
+               goto irq_free_exit;
        }
 
        drvdata->cdev = cdev;
 
+irq_free_exit:
+       if (ret)
+               cci_pci_free_irq(pcidev);
 enum_info_free_exit:
        dfl_fpga_enum_info_free(info);
 
        }
 
        ret = cci_enumerate_feature_devs(pcidev);
-       if (ret) {
-               dev_err(&pcidev->dev, "enumeration failure %d.\n", ret);
-               goto disable_error_report_exit;
-       }
+       if (!ret)
+               return ret;
 
-       return ret;
+       dev_err(&pcidev->dev, "enumeration failure %d.\n", ret);
 
 disable_error_report_exit:
        pci_disable_pcie_error_reporting(pcidev);