]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
cxl/core/regs: Refactor out functions to count regblocks of given type
authorHuaisheng Ye <huaisheng.ye@intel.com>
Wed, 15 Jan 2025 15:26:00 +0000 (23:26 +0800)
committerDave Jiang <dave.jiang@intel.com>
Wed, 22 Jan 2025 15:55:21 +0000 (08:55 -0700)
cxl_find_regblock_instance() counts the number of instances of a register
block as a side effect of searching through all available register blocks.
cxl_count_regblock() throws away that work and recounts all the register
blocks by asking cxl_find_regblock_instance() to redo work it has
already done until it finally returns an error, that is needlessly
wasteful.

Let cxl_count_regblock() leverage the counting that
cxl_find_regblock_instance() already does by passing in a sentinel value
(CXL_INSTANCES_COUNT) that triggers the count to be returned.

[ davej: Updated to more concise commit log supplied by djbw ]
[ davej: Fix up checkpatch formatting warnings ]

Signed-off-by: Huaisheng Ye <huaisheng.ye@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Link: https://patch.msgid.link/20250115152600.26482-2-huaisheng.ye@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/core/regs.c
drivers/cxl/cxl.h
drivers/cxl/pci.c

index 59cb35b40c7e5502ab664afa72135c97575e44ac..117c2e94c761d9b643ac21a90cbcd3d4a6552a83 100644 (file)
@@ -289,21 +289,17 @@ static bool cxl_decode_regblock(struct pci_dev *pdev, u32 reg_lo, u32 reg_hi,
        return true;
 }
 
-/**
- * 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
+/*
+ * __cxl_find_regblock_instance() - Locate a register block or count instances by type / index
+ * Use CXL_INSTANCES_COUNT for @index if counting instances.
  *
- * A CXL DVSEC may point to one or more register blocks, search for them
- * by @type and @index.
+ * __cxl_find_regblock_instance() may return:
+ * 0 - if register block enumerated.
+ * >= 0 - if counting instances.
+ * < 0 - error code otherwise.
  */
-int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
-                              struct cxl_register_map *map, int index)
+static 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;
@@ -342,8 +338,30 @@ int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
        }
 
        map->resource = CXL_RESOURCE_NONE;
+       if (index == CXL_INSTANCES_COUNT)
+               return instance;
+
        return -ENODEV;
 }
+
+/**
+ * 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 and @index.
+ */
+int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
+                              struct cxl_register_map *map, unsigned int index)
+{
+       return __cxl_find_regblock_instance(pdev, type, map, index);
+}
 EXPORT_SYMBOL_NS_GPL(cxl_find_regblock_instance, "CXL");
 
 /**
@@ -360,7 +378,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_find_regblock_instance, "CXL");
 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);
+       return __cxl_find_regblock_instance(pdev, type, map, 0);
 }
 EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, "CXL");
 
@@ -371,19 +389,13 @@ EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, "CXL");
  *
  * Some regblocks may be repeated. Count how many instances.
  *
- * Return: count of matching regblocks.
+ * Return: non-negative count of matching regblocks, negative error code otherwise.
  */
 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++;
-       }
+       return __cxl_find_regblock_instance(pdev, type, &map, CXL_INSTANCES_COUNT);
 }
 EXPORT_SYMBOL_NS_GPL(cxl_count_regblock, "CXL");
 
index fdac3ddb8635b323769ee6089574213ad9792d72..dcf2a127efc7f8d23a469cdc47faa4e471d5017d 100644 (file)
@@ -302,10 +302,11 @@ int cxl_map_device_regs(const struct cxl_register_map *map,
                        struct cxl_device_regs *regs);
 int cxl_map_pmu_regs(struct cxl_register_map *map, struct cxl_pmu_regs *regs);
 
+#define CXL_INSTANCES_COUNT -1
 enum cxl_regloc_type;
 int cxl_count_regblock(struct pci_dev *pdev, enum cxl_regloc_type type);
 int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
-                              struct cxl_register_map *map, int index);
+                              struct cxl_register_map *map, unsigned int index);
 int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
                      struct cxl_register_map *map);
 int cxl_setup_regs(struct cxl_register_map *map);
index 6d94ff4a4f1a62817538ccde3d123714bd8d4a8b..a96e54c6259e1241af93dac21225b5a943dc4eae 100644 (file)
@@ -907,7 +907,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        struct cxl_dev_state *cxlds;
        struct cxl_register_map map;
        struct cxl_memdev *cxlmd;
-       int i, rc, pmu_count;
+       int rc, pmu_count;
+       unsigned int i;
        bool irq_avail;
 
        /*
@@ -1009,6 +1010,9 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                return rc;
 
        pmu_count = cxl_count_regblock(pdev, CXL_REGLOC_RBI_PMU);
+       if (pmu_count < 0)
+               return pmu_count;
+
        for (i = 0; i < pmu_count; i++) {
                struct cxl_pmu_regs pmu_regs;