Skip to content

Commit 19ab69a

Browse files
Robert Richterdjbw
authored andcommitted
cxl/port: Store the port's Component Register mappings in struct cxl_port
CXL capabilities are stored in the Component Registers. To use them, the specific I/O ranges of the capabilities must be determined by probing the registers. For this, the whole Component Register range needs to be mapped temporarily to detect the offset and length of a capability range. In order to use more than one capability of a component (e.g. RAS and HDM) the Component Register are probed and its mappings created multiple times. This also causes overlapping I/O ranges as the whole Component Register range must be mapped again while a capability's I/O range is already mapped. Different capabilities cannot be setup at the same time. E.g. the RAS capability must be made available as soon as the PCI driver is bound, the HDM decoder is setup later during port enumeration. Moreover, during early setup it is still unknown if a certain capability is needed. A central capability setup is therefore not possible, capabilities must be individually enabled once needed during initialization. To avoid a duplicate register probe and overlapping I/O mappings, only probe the Component Registers one time and store the Component Register mapping in struct port. The stored mappings can be used later to iomap the capability register range when enabling the capability, which will be implemented in a follow-on patch. Signed-off-by: Robert Richter <[email protected]> Signed-off-by: Terry Bowman <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dan Williams <[email protected]>
1 parent 733b57f commit 19ab69a

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

drivers/cxl/core/port.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,29 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
688688
return ERR_PTR(rc);
689689
}
690690

691+
static int cxl_setup_comp_regs(struct device *dev, struct cxl_register_map *map,
692+
resource_size_t component_reg_phys)
693+
{
694+
if (component_reg_phys == CXL_RESOURCE_NONE)
695+
return 0;
696+
697+
*map = (struct cxl_register_map) {
698+
.dev = dev,
699+
.reg_type = CXL_REGLOC_RBI_COMPONENT,
700+
.resource = component_reg_phys,
701+
.max_size = CXL_COMPONENT_REG_BLOCK_SIZE,
702+
};
703+
704+
return cxl_setup_regs(map);
705+
}
706+
707+
static inline int cxl_port_setup_regs(struct cxl_port *port,
708+
resource_size_t component_reg_phys)
709+
{
710+
return cxl_setup_comp_regs(&port->dev, &port->comp_map,
711+
component_reg_phys);
712+
}
713+
691714
static struct cxl_port *__devm_cxl_add_port(struct device *host,
692715
struct device *uport_dev,
693716
resource_size_t component_reg_phys,
@@ -711,6 +734,10 @@ static struct cxl_port *__devm_cxl_add_port(struct device *host,
711734
if (rc)
712735
goto err;
713736

737+
rc = cxl_port_setup_regs(port, component_reg_phys);
738+
if (rc)
739+
goto err;
740+
714741
rc = device_add(dev);
715742
if (rc)
716743
goto err;

drivers/cxl/cxl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ struct cxl_dax_region {
547547
* @regions: cxl_region_ref instances, regions mapped by this port
548548
* @parent_dport: dport that points to this port in the parent
549549
* @decoder_ida: allocator for decoder ids
550+
* @comp_map: component register capability mappings
550551
* @nr_dports: number of entries in @dports
551552
* @hdm_end: track last allocated HDM decoder instance for allocation ordering
552553
* @commit_end: cursor to track highest committed decoder for commit ordering
@@ -566,6 +567,7 @@ struct cxl_port {
566567
struct xarray regions;
567568
struct cxl_dport *parent_dport;
568569
struct ida decoder_ida;
570+
struct cxl_register_map comp_map;
569571
int nr_dports;
570572
int hdm_end;
571573
int commit_end;

0 commit comments

Comments
 (0)