Commit 6c7f4f1e authored by Dan Williams's avatar Dan Williams
Browse files

cxl/core/regs: Make cxl_map_{component, device}_regs() device generic



There is no need to carry the barno and the block offset through the
stack, just convert them to a resource base immediately.

Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/166974411035.1608150.8605988708101648442.stgit@djiang5-desk3.ch.intel.com


Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 43a2fb3a
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -54,8 +54,7 @@ static int match_add_dports(struct pci_dev *pdev, void *data)
		dev_dbg(&port->dev, "failed to find component registers\n");

	port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap);
	dport = devm_cxl_add_dport(port, &pdev->dev, port_num,
				   cxl_regmap_to_base(pdev, &map));
	dport = devm_cxl_add_dport(port, &pdev->dev, port_num, map.resource);
	if (IS_ERR(dport)) {
		ctx->error = PTR_ERR(dport);
		return PTR_ERR(dport);
+1 −1
Original line number Diff line number Diff line
@@ -1243,7 +1243,7 @@ static resource_size_t find_component_registers(struct device *dev)
	pdev = to_pci_dev(dev);

	cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map);
	return cxl_regmap_to_base(pdev, &map);
	return map.resource;
}

static int add_port_attach_ep(struct cxl_memdev *cxlmd,
+23 −17
Original line number Diff line number Diff line
@@ -186,17 +186,13 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
	return ret_val;
}

int cxl_map_component_regs(struct pci_dev *pdev,
			   struct cxl_component_regs *regs,
int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs,
			   struct cxl_register_map *map)
{
	struct device *dev = &pdev->dev;
	resource_size_t phys_addr;
	resource_size_t length;

	phys_addr = pci_resource_start(pdev, map->barno);
	phys_addr += map->block_offset;

	phys_addr = map->resource;
	phys_addr += map->component_map.hdm_decoder.offset;
	length = map->component_map.hdm_decoder.size;
	regs->hdm_decoder = devm_cxl_iomap_block(dev, phys_addr, length);
@@ -207,13 +203,11 @@ int cxl_map_component_regs(struct pci_dev *pdev,
}
EXPORT_SYMBOL_NS_GPL(cxl_map_component_regs, CXL);

int cxl_map_device_regs(struct pci_dev *pdev,
int cxl_map_device_regs(struct device *dev,
			struct cxl_device_regs *regs,
			struct cxl_register_map *map)
{
	resource_size_t phys_addr =
		pci_resource_start(pdev, map->barno) + map->block_offset;
	struct device *dev = &pdev->dev;
	resource_size_t phys_addr = map->resource;
	struct mapinfo {
		struct cxl_reg_map *rmap;
		void __iomem **addr;
@@ -243,13 +237,24 @@ int cxl_map_device_regs(struct pci_dev *pdev,
}
EXPORT_SYMBOL_NS_GPL(cxl_map_device_regs, CXL);

static void cxl_decode_regblock(u32 reg_lo, u32 reg_hi,
static bool cxl_decode_regblock(struct pci_dev *pdev, u32 reg_lo, u32 reg_hi,
				struct cxl_register_map *map)
{
	map->block_offset = ((u64)reg_hi << 32) |
	int bar = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo);
	u64 offset = ((u64)reg_hi << 32) |
		     (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK);
	map->barno = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo);

	if (offset > pci_resource_len(pdev, bar)) {
		dev_warn(&pdev->dev,
			 "BAR%d: %pr: too small (offset: %pa, type: %d)\n", bar,
			 &pdev->resource[bar], &offset, map->reg_type);
		return false;
	}

	map->reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, reg_lo);
	map->resource = pci_resource_start(pdev, bar) + offset;
	map->max_size = pci_resource_len(pdev, bar) - offset;
	return true;
}

/**
@@ -269,7 +274,7 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
	u32 regloc_size, regblocks;
	int regloc, i;

	map->block_offset = U64_MAX;
	map->resource = CXL_RESOURCE_NONE;
	regloc = pci_find_dvsec_capability(pdev, PCI_DVSEC_VENDOR_ID_CXL,
					   CXL_DVSEC_REG_LOCATOR);
	if (!regloc)
@@ -287,13 +292,14 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
		pci_read_config_dword(pdev, regloc, &reg_lo);
		pci_read_config_dword(pdev, regloc + 4, &reg_hi);

		cxl_decode_regblock(reg_lo, reg_hi, map);
		if (!cxl_decode_regblock(pdev, reg_lo, reg_hi, map))
			continue;

		if (map->reg_type == type)
			return 0;
	}

	map->block_offset = U64_MAX;
	map->resource = CXL_RESOURCE_NONE;
	return -ENODEV;
}
EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL);
+6 −8
Original line number Diff line number Diff line
@@ -187,17 +187,17 @@ struct cxl_device_reg_map {
/**
 * struct cxl_register_map - DVSEC harvested register block mapping parameters
 * @base: virtual base of the register-block-BAR + @block_offset
 * @block_offset: offset to start of register block in @barno
 * @resource: physical resource base of the register block
 * @max_size: maximum mapping size to perform register search
 * @reg_type: see enum cxl_regloc_type
 * @barno: PCI BAR number containing the register block
 * @component_map: cxl_reg_map for component registers
 * @device_map: cxl_reg_maps for device registers
 */
struct cxl_register_map {
	void __iomem *base;
	u64 block_offset;
	resource_size_t resource;
	resource_size_t max_size;
	u8 reg_type;
	u8 barno;
	union {
		struct cxl_component_reg_map component_map;
		struct cxl_device_reg_map device_map;
@@ -208,11 +208,9 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
			      struct cxl_component_reg_map *map);
void cxl_probe_device_regs(struct device *dev, void __iomem *base,
			   struct cxl_device_reg_map *map);
int cxl_map_component_regs(struct pci_dev *pdev,
			   struct cxl_component_regs *regs,
int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs,
			   struct cxl_register_map *map);
int cxl_map_device_regs(struct pci_dev *pdev,
			struct cxl_device_regs *regs,
int cxl_map_device_regs(struct device *dev, struct cxl_device_regs *regs,
			struct cxl_register_map *map);

enum cxl_regloc_type;
+0 −9
Original line number Diff line number Diff line
@@ -62,15 +62,6 @@ enum cxl_regloc_type {
	CXL_REGLOC_RBI_TYPES
};

static inline resource_size_t cxl_regmap_to_base(struct pci_dev *pdev,
						 struct cxl_register_map *map)
{
	if (map->block_offset == U64_MAX)
		return CXL_RESOURCE_NONE;

	return pci_resource_start(pdev, map->barno) + map->block_offset;
}

int devm_cxl_port_enumerate_dports(struct cxl_port *port);
struct cxl_dev_state;
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm);
Loading