diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-bus-cxl | 15 | ||||
-rw-r--r-- | drivers/cxl/core/port.c | 29 |
2 files changed, 44 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/testing/sysfs-bus-cxl index 8494ef27e8d2..329a7e46c805 100644 --- a/Documentation/ABI/testing/sysfs-bus-cxl +++ b/Documentation/ABI/testing/sysfs-bus-cxl @@ -90,6 +90,21 @@ Description: capability. +What: /sys/bus/cxl/devices/{port,endpoint}X/parent_dport +Date: January, 2023 +KernelVersion: v6.3 +Contact: [email protected] +Description: + (RO) CXL port objects are instantiated for each upstream port in + a CXL/PCIe switch, and for each endpoint to map the + corresponding memory device into the CXL port hierarchy. When a + descendant CXL port (switch or endpoint) is enumerated it is + useful to know which 'dport' object in the parent CXL port + routes to this descendant. The 'parent_dport' symlink points to + the device representing the downstream port of a CXL switch that + routes to {port,endpoint}X. + + What: /sys/bus/cxl/devices/portX/dportY Date: June, 2021 KernelVersion: v5.14 diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index b631a0520456..410c036c09fa 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -583,6 +583,29 @@ static int devm_cxl_link_uport(struct device *host, struct cxl_port *port) return devm_add_action_or_reset(host, cxl_unlink_uport, port); } +static void cxl_unlink_parent_dport(void *_port) +{ + struct cxl_port *port = _port; + + sysfs_remove_link(&port->dev.kobj, "parent_dport"); +} + +static int devm_cxl_link_parent_dport(struct device *host, + struct cxl_port *port, + struct cxl_dport *parent_dport) +{ + int rc; + + if (!parent_dport) + return 0; + + rc = sysfs_create_link(&port->dev.kobj, &parent_dport->dport->kobj, + "parent_dport"); + if (rc) + return rc; + return devm_add_action_or_reset(host, cxl_unlink_parent_dport, port); +} + static struct lock_class_key cxl_port_key; static struct cxl_port *cxl_port_alloc(struct device *uport, @@ -692,6 +715,10 @@ static struct cxl_port *__devm_cxl_add_port(struct device *host, if (rc) return ERR_PTR(rc); + rc = devm_cxl_link_parent_dport(host, port, parent_dport); + if (rc) + return ERR_PTR(rc); + return port; err: @@ -1164,6 +1191,7 @@ static void delete_endpoint(void *data) device_lock(parent); if (parent->driver && !endpoint->dead) { + devm_release_action(parent, cxl_unlink_parent_dport, endpoint); devm_release_action(parent, cxl_unlink_uport, endpoint); devm_release_action(parent, unregister_port, endpoint); } @@ -1194,6 +1222,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_endpoint_autoremove, CXL); */ static void delete_switch_port(struct cxl_port *port) { + devm_release_action(port->dev.parent, cxl_unlink_parent_dport, port); devm_release_action(port->dev.parent, cxl_unlink_uport, port); devm_release_action(port->dev.parent, unregister_port, port); } |