summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2022-06-01 21:49:32 +0200
committerDan Williams <dan.j.williams@intel.com>2022-07-10 21:10:07 +0200
commitee800010835db23c70acc01000f182955cab27a5 (patch)
treebb7678bc2cd22ea26b50b23f772d1124de3e61d9
parenttools/testing/cxl: Fix decoder default state (diff)
downloadlinux-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.c18
-rw-r--r--drivers/cxl/cxl.h2
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;