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.

Signed-off-by: Dan Williams <[email protected]>
---
 drivers/cxl/core/port.c | 16 +++++++++++++++-
 drivers/cxl/cxl.h       |  2 ++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index d2f6898940fa..c48f217e689a 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -546,6 +546,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
@@ -556,14 +557,27 @@ static struct cxl_port *cxl_port_alloc(struct device 
*uport,
        dev = &port->dev;
        if (parent_dport) {
                struct cxl_port *parent_port = parent_dport->port;
+               struct cxl_port *iter;
 
                port->depth = parent_port->depth + 1;
                port->parent_dport = parent_dport;
                dev->parent = &parent_port->dev;
+               /*
+                * 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);
        port->dpa_end = -1;
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 8e2c1b393552..0211cf0d3574 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -331,6 +331,7 @@ struct cxl_nvdimm {
  * @component_reg_phys: component register capability base address (optional)
  * @dead: last ep has been removed, force port re-creation
  * @depth: How deep this port is relative to the root. depth 0 is the root.
+ * @host_bridge: Shortcut to the platform attach point for this port
  */
 struct cxl_port {
        struct device dev;
@@ -344,6 +345,7 @@ struct cxl_port {
        resource_size_t component_reg_phys;
        bool dead;
        unsigned int depth;
+       struct device *host_bridge;
 };
 
 static inline struct cxl_dport *cxl_dport_load(struct cxl_port *port,
-- 
2.36.1


Reply via email to