cxl/port: Introduce port_to_host() helper

In CXL subsystem, a port has its own host device for the port creation
and removal. The host of CXL root and all the first level ports is the
platform firmware device, the host of other ports is their parent port's
device. Create this new helper to much easier to get the host of a cxl
port.

Introduce port_to_host() and use it to replace all places where using
open coded to get the host of a port.

Remove endpoint_host() as its functionality can be replaced by
port_to_host().

[dj: Squashed commit 1 and 3 in the series to commit 1. ]

Signed-off-by: Li Ming <ming.li@zohomail.com>
Tested-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Link: https://patch.msgid.link/20260210-fix-port-enumeration-failure-v3-1-06acce0b9ead@zohomail.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
This commit is contained in:
Li Ming 2026-02-23 09:29:00 -07:00 committed by Dave Jiang
parent 318c58852e
commit 822655e675
2 changed files with 21 additions and 26 deletions

View file

@ -152,6 +152,24 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c);
int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port,
struct access_coordinate *c);
static inline struct device *port_to_host(struct cxl_port *port)
{
struct cxl_port *parent = is_cxl_root(port) ? NULL :
to_cxl_port(port->dev.parent);
/*
* The host of CXL root port and the first level of ports is
* the platform firmware device, the host of all other ports
* is their parent port.
*/
if (!parent)
return port->uport_dev;
else if (is_cxl_root(parent))
return parent->uport_dev;
else
return &parent->dev;
}
static inline struct device *dport_to_host(struct cxl_dport *dport)
{
struct cxl_port *port = dport->port;

View file

@ -615,22 +615,8 @@ struct cxl_port *parent_port_of(struct cxl_port *port)
static void unregister_port(void *_port)
{
struct cxl_port *port = _port;
struct cxl_port *parent = parent_port_of(port);
struct device *lock_dev;
/*
* CXL root port's and the first level of ports are unregistered
* under the platform firmware device lock, all other ports are
* unregistered while holding their parent port lock.
*/
if (!parent)
lock_dev = port->uport_dev;
else if (is_cxl_root(parent))
lock_dev = parent->uport_dev;
else
lock_dev = &parent->dev;
device_lock_assert(lock_dev);
device_lock_assert(port_to_host(port));
port->dead = true;
device_unregister(&port->dev);
}
@ -1427,20 +1413,11 @@ static struct device *grandparent(struct device *dev)
return NULL;
}
static struct device *endpoint_host(struct cxl_port *endpoint)
{
struct cxl_port *port = to_cxl_port(endpoint->dev.parent);
if (is_cxl_root(port))
return port->uport_dev;
return &port->dev;
}
static void delete_endpoint(void *data)
{
struct cxl_memdev *cxlmd = data;
struct cxl_port *endpoint = cxlmd->endpoint;
struct device *host = endpoint_host(endpoint);
struct device *host = port_to_host(endpoint);
scoped_guard(device, host) {
if (host->driver && !endpoint->dead) {
@ -1456,7 +1433,7 @@ static void delete_endpoint(void *data)
int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint)
{
struct device *host = endpoint_host(endpoint);
struct device *host = port_to_host(endpoint);
struct device *dev = &cxlmd->dev;
get_device(host);