On 01.12.22 13:34:16, Dan Williams wrote: > Unlike a CXL memory expander in a VH topology that has at least one > intervening 'struct cxl_port' instance between itself and the CXL root > device, an RCD attaches one-level higher. For example: > > VH > ┌──────────┐ > │ ACPI0017 │ > │ root0 │ > └─────┬────┘ > │ > ┌─────┴────┐ > │ dport0 │ > ┌─────┤ ACPI0016 ├─────┐ > │ │ port1 │ │ > │ └────┬─────┘ │ > │ │ │ > ┌──┴───┐ ┌──┴───┐ ┌───┴──┐ > │dport0│ │dport1│ │dport2│ > │ RP0 │ │ RP1 │ │ RP2 │ > └──────┘ └──┬───┘ └──────┘ > │ > ┌───┴─────┐ > │endpoint0│ > │ port2 │ > └─────────┘ > > ...vs: > > RCH > ┌──────────┐ > │ ACPI0017 │ > │ root0 │ > └────┬─────┘ > │ > ┌───┴────┐ > │ dport0 │ > │ACPI0016│ > └───┬────┘ > │ > ┌────┴─────┐ > │endpoint0 │ > │ port1 │ > └──────────┘ > > So arrange for endpoint port in the RCH/RCD case to appear directly > connected to the host-bridge in its singular role as a dport. Compare > that to the VH case where the host-bridge serves a dual role as a > 'cxl_dport' for the CXL root device *and* a 'cxl_port' upstream port for > the Root Ports in the Root Complex that are modeled as 'cxl_dport' > instances in the CXL topology. > > Another deviation from the VH case is that RCDs may need to look up > their component registers from the Root Complex Register Block (RCRB). > That platform firmware specified RCRB area is cached by the cxl_acpi > driver and conveyed via the host-bridge dport to the cxl_mem driver to > perform the cxl_rcrb_to_component() lookup for the endpoint port > (See 9.11.8 CXL Devices Attached to an RCH for the lookup of the > upstream port component registers). > > Tested-by: Robert Richter <rrich...@amd.com>
With the one comment below addressed you can also add my: Reviewed-by: Robert Richter <rrich...@amd.com> > Signed-off-by: Dan Williams <dan.j.willi...@intel.com> > --- > drivers/cxl/core/port.c | 7 +++++++ > drivers/cxl/cxlmem.h | 2 ++ > drivers/cxl/mem.c | 31 ++++++++++++++++++++++++------- > drivers/cxl/pci.c | 10 ++++++++++ > 4 files changed, 43 insertions(+), 7 deletions(-) > diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c > @@ -119,17 +131,22 @@ static int cxl_mem_probe(struct device *dev) > return -ENXIO; > } > > - device_lock(&parent_port->dev); > - if (!parent_port->dev.driver) { > + if (dport->rch) > + endpoint_parent = parent_port->uport; > + else > + endpoint_parent = &parent_port->dev; > + > + device_lock(endpoint_parent); > + if (!endpoint_parent->driver) { > dev_err(dev, "CXL port topology %s not enabled\n", > dev_name(&parent_port->dev)); Already reported: dev_name(endpoint_parent) > rc = -ENXIO; > goto unlock; > } > > - rc = devm_cxl_add_endpoint(cxlmd, dport); > + rc = devm_cxl_add_endpoint(endpoint_parent, cxlmd, dport); > unlock: > - device_unlock(&parent_port->dev); > + device_unlock(endpoint_parent); > put_device(&parent_port->dev); > if (rc) > return rc;