}
 
 /**
- * cxl_find_regblock() - Locate register blocks by type
+ * cxl_find_regblock_instance() - Locate a register block by type / index
  * @pdev: The CXL PCI device to enumerate.
  * @type: Register Block Indicator id
  * @map: Enumeration output, clobbered on error
+ * @index: Index into which particular instance of a regblock wanted in the
+ *        order found in register locator DVSEC.
  *
  * Return: 0 if register block enumerated, negative error code otherwise
  *
  * A CXL DVSEC may point to one or more register blocks, search for them
- * by @type.
+ * by @type and @index.
  */
-int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
-                     struct cxl_register_map *map)
+int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
+                              struct cxl_register_map *map, int index)
 {
        u32 regloc_size, regblocks;
+       int instance = 0;
        int regloc, i;
 
        map->resource = CXL_RESOURCE_NONE;
                if (!cxl_decode_regblock(pdev, reg_lo, reg_hi, map))
                        continue;
 
-               if (map->reg_type == type)
-                       return 0;
+               if (map->reg_type == type) {
+                       if (index == instance)
+                               return 0;
+                       instance++;
+               }
        }
 
        map->resource = CXL_RESOURCE_NONE;
        return -ENODEV;
 }
+EXPORT_SYMBOL_NS_GPL(cxl_find_regblock_instance, CXL);
+
+/**
+ * cxl_find_regblock() - Locate register blocks by type
+ * @pdev: The CXL PCI device to enumerate.
+ * @type: Register Block Indicator id
+ * @map: Enumeration output, clobbered on error
+ *
+ * Return: 0 if register block enumerated, negative error code otherwise
+ *
+ * A CXL DVSEC may point to one or more register blocks, search for them
+ * by @type.
+ */
+int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
+                     struct cxl_register_map *map)
+{
+       return cxl_find_regblock_instance(pdev, type, map, 0);
+}
 EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL);
 
+/**
+ * cxl_count_regblock() - Count instances of a given regblock type.
+ * @pdev: The CXL PCI device to enumerate.
+ * @type: Register Block Indicator id
+ *
+ * Some regblocks may be repeated. Count how many instances.
+ *
+ * Return: count of matching regblocks.
+ */
+int cxl_count_regblock(struct pci_dev *pdev, enum cxl_regloc_type type)
+{
+       struct cxl_register_map map;
+       int rc, count = 0;
+
+       while (1) {
+               rc = cxl_find_regblock_instance(pdev, type, &map, count);
+               if (rc)
+                       return count;
+               count++;
+       }
+}
+EXPORT_SYMBOL_NS_GPL(cxl_count_regblock, CXL);
+
 resource_size_t cxl_rcrb_to_component(struct device *dev,
                                      resource_size_t rcrb,
                                      enum cxl_rcrb which)