diff options
author | Dan Williams <dan.j.williams@intel.com> | 2022-06-01 21:49:32 +0200 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2022-07-10 21:10:07 +0200 |
commit | ee800010835db23c70acc01000f182955cab27a5 (patch) | |
tree | bb7678bc2cd22ea26b50b23f772d1124de3e61d9 | |
parent | tools/testing/cxl: Fix decoder default state (diff) | |
download | linux-ee800010835db23c70acc01000f182955cab27a5.tar.xz linux-ee800010835db23c70acc01000f182955cab27a5.zip |
cxl/port: Cache CXL host bridge data
Region creation has need for checking host-bridge connectivity when
adding endpoints to regions. Record, at port creation time, the
host-bridge to provide a useful shortcut from any location in the
topology to the most-significant ancestor.
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/20220624041950.559155-4-dan.j.williams@intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | drivers/cxl/core/port.c | 18 | ||||
-rw-r--r-- | drivers/cxl/cxl.h | 2 |
2 files changed, 19 insertions, 1 deletions
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index 9175d30e1755..f62c0a6e17ea 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -392,6 +392,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport, if (rc < 0) goto err; port->id = rc; + port->uport = uport; /* * The top-level cxl_port "cxl_root" does not have a cxl_port as @@ -401,12 +402,27 @@ static struct cxl_port *cxl_port_alloc(struct device *uport, */ dev = &port->dev; if (parent_port) { + struct cxl_port *iter; + dev->parent = &parent_port->dev; port->depth = parent_port->depth + 1; + + /* + * walk to the host bridge, or the first ancestor that knows + * the host bridge + */ + iter = port; + while (!iter->host_bridge && + !is_cxl_root(to_cxl_port(iter->dev.parent))) + iter = to_cxl_port(iter->dev.parent); + if (iter->host_bridge) + port->host_bridge = iter->host_bridge; + else + port->host_bridge = iter->uport; + dev_dbg(uport, "host-bridge: %s\n", dev_name(port->host_bridge)); } else dev->parent = uport; - port->uport = uport; port->component_reg_phys = component_reg_phys; ida_init(&port->decoder_ida); INIT_LIST_HEAD(&port->dports); diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index fd02f9e2a829..79d4c361b54f 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -282,6 +282,7 @@ struct cxl_nvdimm { * decode hierarchy. * @dev: this port's device * @uport: PCI or platform device implementing the upstream port capability + * @host_bridge: Shortcut to the platform attach point for this port * @id: id for port device-name * @dports: cxl_dport instances referenced by decoders * @endpoints: cxl_ep instances, endpoints that are a descendant of this port @@ -293,6 +294,7 @@ struct cxl_nvdimm { struct cxl_port { struct device dev; struct device *uport; + struct device *host_bridge; int id; struct list_head dports; struct list_head endpoints; |