Commit 822655e6 authored by Li Ming's avatar Li Ming Committed by Dave Jiang
Browse files

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: default avatarLi Ming <ming.li@zohomail.com>
Tested-by: default avatarAlison Schofield <alison.schofield@intel.com>
Reviewed-by: default avatarDan Williams <dan.j.williams@intel.com>
Link: https://patch.msgid.link/20260210-fix-port-enumeration-failure-v3-1-06acce0b9ead@zohomail.com


Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
parent 318c5885
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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;
+3 −26
Original line number Diff line number Diff line
@@ -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);