cxl/port: Cache CXL host bridge data
authorDan Williams <dan.j.williams@intel.com>
Wed, 1 Jun 2022 19:49:32 +0000 (12:49 -0700)
committerDan Williams <dan.j.williams@intel.com>
Sun, 10 Jul 2022 19:10:07 +0000 (12:10 -0700)
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>
drivers/cxl/core/port.c
drivers/cxl/cxl.h

index 9175d30..f62c0a6 100644 (file)
@@ -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);
index fd02f9e..79d4c36 100644 (file)
@@ -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;