Skip to content

Commit f6ee249

Browse files
committed
cxl: Move port register setup to when first dport appear
This patch moves the port register setup to when the first dport appears via the memdev probe path. At this point, the CXL link should be established and the register access is expected to succeed. This change addresses an error message observed when PCIe hotplug is enabled on an Intel platform. The error messages "cxl portN: Couldn't locate the CXL.cache and CXL.mem capability array header" is observed for the host bridge (CHBCR) during cxl_acpi driver probe. If the cxl_acpi module probe is running before the CXL link between the endpoint device and the RP is established, then the platform may not have exposed DVSEC ID 3 and/or DVSEC ID 7 blocks which will trigger the error message. This behavior is defined by the CXL spec r3.2 9.12.3 for RPs and DSPs, however the Intel platform also added this behavior to the host bridge. This change also needs the dport enumeration to be moved to the memdev probe path in order to address the issue. This change is not a wholly contained solution by itself. [dj: Add missing var init during port alloc] Suggested-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Tested-by: Robert Richter <rrichter@amd.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent d64035a commit f6ee249

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

drivers/cxl/core/port.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
749749
xa_init(&port->dports);
750750
xa_init(&port->endpoints);
751751
xa_init(&port->regions);
752+
port->component_reg_phys = CXL_RESOURCE_NONE;
752753

753754
device_initialize(dev);
754755
lockdep_set_class_and_subclass(&dev->mutex, &cxl_port_key, port->depth);
@@ -867,9 +868,7 @@ static int cxl_port_add(struct cxl_port *port,
867868
if (rc)
868869
return rc;
869870

870-
rc = cxl_port_setup_regs(port, component_reg_phys);
871-
if (rc)
872-
return rc;
871+
port->component_reg_phys = component_reg_phys;
873872
} else {
874873
rc = dev_set_name(dev, "root%d", port->id);
875874
if (rc)
@@ -1200,6 +1199,18 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
12001199

12011200
cxl_debugfs_create_dport_dir(dport);
12021201

1202+
/*
1203+
* Setup port register if this is the first dport showed up. Having
1204+
* a dport also means that there is at least 1 active link.
1205+
*/
1206+
if (port->nr_dports == 1 &&
1207+
port->component_reg_phys != CXL_RESOURCE_NONE) {
1208+
rc = cxl_port_setup_regs(port, port->component_reg_phys);
1209+
if (rc)
1210+
return ERR_PTR(rc);
1211+
port->component_reg_phys = CXL_RESOURCE_NONE;
1212+
}
1213+
12031214
return dport;
12041215
}
12051216

drivers/cxl/cxl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ struct cxl_dax_region {
599599
* @cdat: Cached CDAT data
600600
* @cdat_available: Should a CDAT attribute be available in sysfs
601601
* @pci_latency: Upstream latency in picoseconds
602+
* @component_reg_phys: Physical address of component register
602603
*/
603604
struct cxl_port {
604605
struct device dev;
@@ -622,6 +623,7 @@ struct cxl_port {
622623
} cdat;
623624
bool cdat_available;
624625
long pci_latency;
626+
resource_size_t component_reg_phys;
625627
};
626628

627629
/**

0 commit comments

Comments
 (0)