Commit 448a60e8 authored by Huaisheng Ye's avatar Huaisheng Ye Committed by Dave Jiang
Browse files

cxl/core/regs: Refactor out functions to count regblocks of given type



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: default avatarHuaisheng Ye <huaisheng.ye@intel.com>
Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: default avatarDan Williams <dan.j.williams@intel.com>
Link: https://patch.msgid.link/20250115152600.26482-2-huaisheng.ye@intel.com


Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
parent 6cdbd84d
Loading
Loading
Loading
Loading
+34 −22
Original line number Diff line number Diff line
@@ -289,20 +289,16 @@ 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,
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;
@@ -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");

+2 −1
Original line number Diff line number Diff line
@@ -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);
+5 −1
Original line number Diff line number Diff line
@@ -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;