Commit a1554e9c authored by Dan Williams's avatar Dan Williams

cxl/pci: Prepare for mapping RAS Capability Structure

The RAS Capabilitiy Structure is a CXL Component register capability
block. Unlike the HDM Decoder Capability, it will be referenced by the
cxl_pci driver in response to PCIe AER events. Due to this it is no
longer the case that cxl_map_component_regs() can assume that it should
map all component registers. Plumb a bitmask of capability ids to map
through cxl_map_component_regs().

For symmetry cxl_probe_device_regs() is updated to populate @id in
'struct cxl_reg_map' even though cxl_map_device_regs() does not have a
need to map a subset of the device registers per caller.
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/166974412214.1608150.11487843455070795378.stgit@djiang5-desk3.ch.intel.comSigned-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 920d8d2c
...@@ -97,7 +97,8 @@ static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb, ...@@ -97,7 +97,8 @@ static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb,
return -ENXIO; return -ENXIO;
} }
return cxl_map_component_regs(&port->dev, regs, &map); return cxl_map_component_regs(&port->dev, regs, &map,
BIT(CXL_CM_CAP_CAP_ID_HDM));
} }
/** /**
......
...@@ -92,6 +92,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, ...@@ -92,6 +92,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
if (!rmap) if (!rmap)
continue; continue;
rmap->valid = true; rmap->valid = true;
rmap->id = cap_id;
rmap->offset = CXL_CM_OFFSET + offset; rmap->offset = CXL_CM_OFFSET + offset;
rmap->size = length; rmap->size = length;
} }
...@@ -159,6 +160,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base, ...@@ -159,6 +160,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
if (!rmap) if (!rmap)
continue; continue;
rmap->valid = true; rmap->valid = true;
rmap->id = cap_id;
rmap->offset = offset; rmap->offset = offset;
rmap->size = length; rmap->size = length;
} }
...@@ -187,17 +189,31 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr, ...@@ -187,17 +189,31 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
} }
int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs, int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs,
struct cxl_register_map *map) struct cxl_register_map *map, unsigned long map_mask)
{ {
resource_size_t phys_addr; struct mapinfo {
resource_size_t length; struct cxl_reg_map *rmap;
void __iomem **addr;
phys_addr = map->resource; } mapinfo[] = {
phys_addr += map->component_map.hdm_decoder.offset; { &map->component_map.hdm_decoder, &regs->hdm_decoder },
length = map->component_map.hdm_decoder.size; };
regs->hdm_decoder = devm_cxl_iomap_block(dev, phys_addr, length); int i;
if (!regs->hdm_decoder)
return -ENOMEM; for (i = 0; i < ARRAY_SIZE(mapinfo); i++) {
struct mapinfo *mi = &mapinfo[i];
resource_size_t phys_addr;
resource_size_t length;
if (!mi->rmap->valid)
continue;
if (!test_bit(mi->rmap->id, &map_mask))
continue;
phys_addr = map->resource + mi->rmap->offset;
length = mi->rmap->size;
*(mi->addr) = devm_cxl_iomap_block(dev, phys_addr, length);
if (!*(mi->addr))
return -ENOMEM;
}
return 0; return 0;
} }
......
...@@ -170,6 +170,7 @@ struct cxl_regs { ...@@ -170,6 +170,7 @@ struct cxl_regs {
struct cxl_reg_map { struct cxl_reg_map {
bool valid; bool valid;
int id;
unsigned long offset; unsigned long offset;
unsigned long size; unsigned long size;
}; };
...@@ -209,7 +210,8 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, ...@@ -209,7 +210,8 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
void cxl_probe_device_regs(struct device *dev, void __iomem *base, void cxl_probe_device_regs(struct device *dev, void __iomem *base,
struct cxl_device_reg_map *map); struct cxl_device_reg_map *map);
int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs, int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs,
struct cxl_register_map *map); struct cxl_register_map *map,
unsigned long map_mask);
int cxl_map_device_regs(struct device *dev, struct cxl_device_regs *regs, int cxl_map_device_regs(struct device *dev, struct cxl_device_regs *regs,
struct cxl_register_map *map); struct cxl_register_map *map);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment