Skip to content

Commit 33d9c98

Browse files
committed
cxl/port: Fix @host confusion in cxl_dport_setup_regs()
commit 5d2ffbe ("cxl/port: Store the downstream port's Component Register mappings in struct cxl_dport") ...moved the dport component registers from a raw component_reg_phys passed in at dport instantiation time to a 'struct cxl_register_map' populated with both the component register data *and* the "host" device for mapping operations. While typical CXL switch dports are mapped by their associated 'struct cxl_port', an RCH host bridge dport registered by cxl_acpi needs to wait until the cxl_mem driver makes the attachment to map the registers. This is because there are no intervening 'struct cxl_port' instances between the root cxl_port and the endpoint port in an RCH topology. For now just mark the host as NULL in the RCH dport case until code that needs to map the dport registers arrives. This patch is not flagged for -stable since nothing in the current driver uses the dport->comp_map. Now, I am slightly uneasy that cxl_setup_comp_regs() sets map->host to a wrong value and then cxl_dport_setup_regs() fixes it up, but the alternatives I came up with are more messy. For example, adding an @logdev to 'struct cxl_register_map' that the dev_printk()s can fall back to when @host is NULL. I settled on "post-fixup+comment" since it is only RCH dports that have this special case where register probing is split between a host-bridge RCRB lookup and when cxl_mem_probe() does the association of the cxl_memdev and endpoint port. [moved rename of @comp_map to @reg_map into next patch] Fixes: 5d2ffbe ("cxl/port: Store the downstream port's Component Register mappings in struct cxl_dport") Signed-off-by: Robert Richter <rrichter@amd.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Link: https://lore.kernel.org/r/20231018171713.1883517-4-rrichter@amd.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent dd22581 commit 33d9c98

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

drivers/cxl/core/port.c

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -716,13 +716,23 @@ static int cxl_port_setup_regs(struct cxl_port *port,
716716
component_reg_phys);
717717
}
718718

719-
static int cxl_dport_setup_regs(struct cxl_dport *dport,
719+
static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
720720
resource_size_t component_reg_phys)
721721
{
722+
int rc;
723+
722724
if (dev_is_platform(dport->dport_dev))
723725
return 0;
724-
return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map,
725-
component_reg_phys);
726+
727+
/*
728+
* use @dport->dport_dev for the context for error messages during
729+
* register probing, and fixup @host after the fact, since @host may be
730+
* NULL.
731+
*/
732+
rc = cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map,
733+
component_reg_phys);
734+
dport->comp_map.host = host;
735+
return rc;
726736
}
727737

728738
static struct cxl_port *__devm_cxl_add_port(struct device *host,
@@ -983,7 +993,16 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
983993
if (!dport)
984994
return ERR_PTR(-ENOMEM);
985995

986-
if (rcrb != CXL_RESOURCE_NONE) {
996+
dport->dport_dev = dport_dev;
997+
dport->port_id = port_id;
998+
dport->port = port;
999+
1000+
if (rcrb == CXL_RESOURCE_NONE) {
1001+
rc = cxl_dport_setup_regs(&port->dev, dport,
1002+
component_reg_phys);
1003+
if (rc)
1004+
return ERR_PTR(rc);
1005+
} else {
9871006
dport->rcrb.base = rcrb;
9881007
component_reg_phys = __rcrb_to_component(dport_dev, &dport->rcrb,
9891008
CXL_RCRB_DOWNSTREAM);
@@ -992,21 +1011,21 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
9921011
return ERR_PTR(-ENXIO);
9931012
}
9941013

1014+
/*
1015+
* RCH @dport is not ready to map until associated with its
1016+
* memdev
1017+
*/
1018+
rc = cxl_dport_setup_regs(NULL, dport, component_reg_phys);
1019+
if (rc)
1020+
return ERR_PTR(rc);
1021+
9951022
dport->rch = true;
9961023
}
9971024

9981025
if (component_reg_phys != CXL_RESOURCE_NONE)
9991026
dev_dbg(dport_dev, "Component Registers found for dport: %pa\n",
10001027
&component_reg_phys);
10011028

1002-
dport->dport_dev = dport_dev;
1003-
dport->port_id = port_id;
1004-
dport->port = port;
1005-
1006-
rc = cxl_dport_setup_regs(dport, component_reg_phys);
1007-
if (rc)
1008-
return ERR_PTR(rc);
1009-
10101029
cond_cxl_root_lock(port);
10111030
rc = add_dport(port, dport);
10121031
cond_cxl_root_unlock(port);

0 commit comments

Comments
 (0)