Linux CXL
 help / color / mirror / Atom feed
From: Ben Cheatham <Benjamin.Cheatham@amd.com>
To: <linux-cxl@vger.kernel.org>, <dave@stgolabs.net>,
	<jic23@kernel.org>, <dave.jiang@intel.com>,
	<alison.schofield@intel.com>
Cc: <linux-iommu@vger.kernel.org>, <benjamin.cheatham@amd.com>,
	<terry.bowman@amd.com>, <robert.richter@amd.com>
Subject: [PATCH 04/15] cxl/core: Update devm_cxl_enumerate_ports() for cxl_cachedevs
Date: Wed, 23 Sep 2026 12:33:31 -0500	[thread overview]
Message-ID: <20260923173342.5584-5-Benjamin.Cheatham@amd.com> (raw)
In-Reply-To: <20260923173342.5584-1-Benjamin.Cheatham@amd.com>

Update devm_cxl_enumerate_ports() to use a struct device pointer instead
of struct cxl_memdev pointer to prepare for adding cxl_cachedevs to the
port hierarchy.

No functional change intended.

Signed-off-by: Ben Cheatham <Benjamin.Cheatham@amd.com>
---
 drivers/cxl/core/port.c | 95 ++++++++++++++++++++++++++++-------------
 drivers/cxl/cxl.h       |  2 +-
 drivers/cxl/mem.c       |  2 +-
 3 files changed, 67 insertions(+), 32 deletions(-)

diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 6181ec730ec2..506461d5db22 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -839,6 +839,28 @@ static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
 			    &cxl_einj_inject_fops);
 }
 
+static struct cxl_dev_state *cxl_ep_to_cxlds(struct device *ep_dev)
+{
+	if (is_cxl_memdev(ep_dev))
+		return to_cxl_memdev(ep_dev)->cxlds;
+
+	if (is_cxl_cachedev(ep_dev))
+		return to_cxl_cachedev(ep_dev)->cxlds;
+
+	return NULL;
+}
+
+static struct cxl_port **cxl_ep_get_endpoint_port(struct device *ep_dev)
+{
+	if (is_cxl_memdev(ep_dev))
+		return &to_cxl_memdev(ep_dev)->endpoint;
+
+	if (is_cxl_cachedev(ep_dev))
+		return &to_cxl_cachedev(ep_dev)->endpoint;
+
+	return NULL;
+}
+
 static int cxl_port_add(struct cxl_port *port,
 			resource_size_t component_reg_phys,
 			struct cxl_dport *parent_dport)
@@ -846,9 +868,10 @@ static int cxl_port_add(struct cxl_port *port,
 	struct device *dev __free(put_device) = &port->dev;
 	int rc;
 
-	if (is_cxl_memdev(port->uport_dev)) {
-		struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
-		struct cxl_dev_state *cxlds = cxlmd->cxlds;
+	if (is_cxl_memdev(port->uport_dev) ||
+	    is_cxl_cachedev(port->uport_dev)) {
+		struct cxl_dev_state *cxlds = cxl_ep_to_cxlds(port->uport_dev);
+		struct cxl_port **endpoint = cxl_ep_get_endpoint_port(port->uport_dev);
 
 		rc = dev_set_name(dev, "endpoint%d", port->id);
 		if (rc)
@@ -861,7 +884,7 @@ static int cxl_port_add(struct cxl_port *port,
 		 */
 		port->reg_map = cxlds->reg_map;
 		port->reg_map.host = &port->dev;
-		cxlmd->endpoint = port;
+		*endpoint = port;
 	} else if (parent_dport) {
 		rc = dev_set_name(dev, "port%d", port->id);
 		if (rc)
@@ -1488,11 +1511,11 @@ static void del_dports(struct cxl_port *port)
 }
 
 struct detach_ctx {
-	struct cxl_memdev *cxlmd;
+	struct device *ep_dev;
 	int depth;
 };
 
-static int port_has_memdev(struct device *dev, const void *data)
+static int port_has_ep_dev(struct device *dev, const void *data)
 {
 	const struct detach_ctx *ctx = data;
 	struct cxl_port *port;
@@ -1504,24 +1527,33 @@ static int port_has_memdev(struct device *dev, const void *data)
 	if (port->depth != ctx->depth)
 		return 0;
 
-	return !!cxl_ep_load(port, &ctx->cxlmd->dev);
+	return !!cxl_ep_load(port, ctx->ep_dev);
+}
+
+static int cxl_ep_get_depth(struct device *ep_dev)
+{
+	if (is_cxl_memdev(ep_dev))
+		return to_cxl_memdev(ep_dev)->depth;
+	else
+		return to_cxl_cachedev(ep_dev)->depth;
 }
 
 static void cxl_detach_ep(void *data)
 {
-	struct cxl_memdev *cxlmd = data;
+	struct device *ep_dev = data;
+	int depth = cxl_ep_get_depth(ep_dev);
 
-	for (int i = cxlmd->depth - 1; i >= 1; i--) {
+	for (int i = depth - 1; i >= 1; i--) {
 		struct cxl_port *port, *parent_port;
 		struct detach_ctx ctx = {
-			.cxlmd = cxlmd,
+			.ep_dev = ep_dev,
 			.depth = i,
 		};
 		struct cxl_ep *ep;
 		bool died = false;
 
 		struct device *dev __free(put_device) =
-			bus_find_device(&cxl_bus_type, NULL, &ctx, port_has_memdev);
+			bus_find_device(&cxl_bus_type, NULL, &ctx, port_has_ep_dev);
 		if (!dev)
 			continue;
 		port = to_cxl_port(dev);
@@ -1529,8 +1561,8 @@ static void cxl_detach_ep(void *data)
 		parent_port = to_cxl_port(port->dev.parent);
 		device_lock(&parent_port->dev);
 		device_lock(&port->dev);
-		ep = cxl_ep_load(port, &cxlmd->dev);
-		dev_dbg(&cxlmd->dev, "disconnect %s from %s\n",
+		ep = cxl_ep_load(port, ep_dev);
+		dev_dbg(ep_dev, "disconnect %s from %s\n",
 			ep ? dev_name(ep->ep) : "", dev_name(&port->dev));
 		cxl_ep_remove(port, ep);
 		if (ep && !port->dead && xa_empty(&port->endpoints) &&
@@ -1547,7 +1579,7 @@ static void cxl_detach_ep(void *data)
 		device_unlock(&port->dev);
 
 		if (died) {
-			dev_dbg(&cxlmd->dev, "delete %s\n",
+			dev_dbg(ep_dev, "delete %s\n",
 				dev_name(&port->dev));
 			delete_switch_port(port);
 		}
@@ -1582,8 +1614,8 @@ static int match_port_by_uport(struct device *dev, const void *data)
 		return 0;
 
 	port = to_cxl_port(dev);
-	/* Endpoint ports are hosted by memdevs */
-	if (is_cxl_memdev(port->uport_dev))
+	/* Endpoint ports are hosted by memdevs or cachedevs */
+	if (is_cxl_memdev(port->uport_dev) || is_cxl_cachedev(port->uport_dev))
 		return uport_dev == port->uport_dev->parent;
 	return uport_dev == port->uport_dev;
 }
@@ -1722,7 +1754,7 @@ static struct cxl_dport *devm_cxl_create_port(struct device *ep_dev,
 	return probe_dport(port, dport_dev);
 }
 
-static int add_port_attach_ep(struct cxl_memdev *cxlmd,
+static int add_port_attach_ep(struct device *ep_dev,
 			      struct device *uport_dev,
 			      struct device *dport_dev)
 {
@@ -1736,7 +1768,7 @@ static int add_port_attach_ep(struct cxl_memdev *cxlmd,
 		 * CXL-root 'cxl_port' on a previous iteration, fail for now to
 		 * be re-probed after platform driver attaches.
 		 */
-		dev_dbg(&cxlmd->dev, "%s is a root dport\n",
+		dev_dbg(ep_dev, "%s is a root dport\n",
 			dev_name(dport_dev));
 		return -ENXIO;
 	}
@@ -1756,7 +1788,7 @@ static int add_port_attach_ep(struct cxl_memdev *cxlmd,
 				return PTR_ERR(parent_dport);
 		}
 
-		dport = devm_cxl_create_port(&cxlmd->dev, parent_port,
+		dport = devm_cxl_create_port(ep_dev, parent_port,
 					     parent_dport, uport_dev,
 					     dport_dev);
 		if (IS_ERR(dport)) {
@@ -1767,7 +1799,7 @@ static int add_port_attach_ep(struct cxl_memdev *cxlmd,
 		}
 	}
 
-	rc = cxl_add_ep(dport, &cxlmd->dev);
+	rc = cxl_add_ep(dport, ep_dev);
 	if (rc == -EBUSY) {
 		/*
 		 * "can't" happen, but this error code means
@@ -1807,20 +1839,23 @@ static struct cxl_dport *find_or_add_dport(struct cxl_port *port,
 	return dport;
 }
 
-int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd)
+int devm_cxl_enumerate_ports(struct device *ep_dev)
 {
-	struct device *dev = &cxlmd->dev;
+	struct cxl_dev_state *cxlds = cxl_ep_to_cxlds(ep_dev);
 	struct device *iter;
 	int rc;
 
+	if (!cxlds)
+		return -EINVAL;
+
 	/*
 	 * Skip intermediate port enumeration in the RCH case, there
 	 * are no ports in between a host bridge and an endpoint.
 	 */
-	if (cxlmd->cxlds->rcd)
+	if (cxlds->rcd)
 		return 0;
 
-	rc = devm_add_action_or_reset(&cxlmd->dev, cxl_detach_ep, cxlmd);
+	rc = devm_add_action_or_reset(ep_dev, cxl_detach_ep, ep_dev);
 	if (rc)
 		return rc;
 
@@ -1830,7 +1865,7 @@ int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd)
 	 * attempt fails.
 	 */
 retry:
-	for (iter = dev; iter; iter = grandparent(iter)) {
+	for (iter = ep_dev; iter; iter = grandparent(iter)) {
 		struct device *dport_dev = grandparent(iter);
 		struct device *uport_dev;
 		struct cxl_dport *dport;
@@ -1840,18 +1875,18 @@ int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd)
 
 		uport_dev = dport_dev->parent;
 		if (!uport_dev) {
-			dev_warn(dev, "at %s no parent for dport: %s\n",
+			dev_warn(ep_dev, "at %s no parent for dport: %s\n",
 				 dev_name(iter), dev_name(dport_dev));
 			return -ENXIO;
 		}
 
-		dev_dbg(dev, "scan: iter: %s dport_dev: %s parent: %s\n",
+		dev_dbg(ep_dev, "scan: iter: %s dport_dev: %s parent: %s\n",
 			dev_name(iter), dev_name(dport_dev),
 			dev_name(uport_dev));
 		struct cxl_port *port __free(put_cxl_port) =
 			find_cxl_port_by_uport(uport_dev);
 		if (port) {
-			dev_dbg(&cxlmd->dev,
+			dev_dbg(ep_dev,
 				"found already registered port %s:%s\n",
 				dev_name(&port->dev),
 				dev_name(port->uport_dev));
@@ -1867,7 +1902,7 @@ int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd)
 				return PTR_ERR(dport);
 			}
 
-			rc = cxl_add_ep(dport, &cxlmd->dev);
+			rc = cxl_add_ep(dport, ep_dev);
 
 			/*
 			 * If the endpoint already exists in the port's list,
@@ -1888,7 +1923,7 @@ int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd)
 			return 0;
 		}
 
-		rc = add_port_attach_ep(cxlmd, uport_dev, dport_dev);
+		rc = add_port_attach_ep(ep_dev, uport_dev, dport_dev);
 		/* port missing, try to add parent */
 		if (rc == -EAGAIN)
 			continue;
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 72d2686a408b..7d369030198a 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -744,7 +744,7 @@ DEFINE_FREE(put_cxl_root_decoder, struct cxl_root_decoder *, if (!IS_ERR_OR_NULL
 DEFINE_FREE(put_cxl_region, struct cxl_region *, if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev))
 DEFINE_FREE(put_cxl_dax_region, struct cxl_dax_region *, if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev))
 
-int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd);
+int devm_cxl_enumerate_ports(struct device *epdev);
 void cxl_bus_rescan(void);
 void cxl_bus_drain(void);
 struct cxl_port *cxl_pci_find_port(struct pci_dev *pdev,
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index 798e5c369cfc..b18dcce2e8a6 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -128,7 +128,7 @@ static int cxl_mem_probe(struct device *dev)
 	if (rc)
 		return rc;
 
-	rc = devm_cxl_enumerate_ports(cxlmd);
+	rc = devm_cxl_enumerate_ports(&cxlmd->dev);
 	if (rc)
 		return rc;
 
-- 
2.53.0


  parent reply	other threads:[~2026-09-23 17:33 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-23 17:33 [PATCH 00/15] Add initial CXL.cache support Ben Cheatham
2026-09-23 17:33 ` [PATCH 01/15] cxl/core: Add CXL.cache device struct Ben Cheatham
2026-09-23 17:41   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 02/15] cxl/cache: Add cxl_cache driver Ben Cheatham
2026-09-23 17:49   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 03/15] cxl/core: Change cxl_ep_load() to use device pointer parameter Ben Cheatham
2026-09-23 17:33 ` Ben Cheatham [this message]
2026-09-23 17:33 ` [PATCH 05/15] cxl/port: Split endpoint port probe on device type Ben Cheatham
2026-09-23 17:46   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 06/15] cxl/core: Update devm_cxl_add_endpoint() for cxl_cachedevs Ben Cheatham
2026-09-23 17:51   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 07/15] cxl/cache: Verify port hierarchy has CXL.cache enabled Ben Cheatham
2026-09-23 17:33 ` [PATCH 08/15] cxl/core, cache: Add Cache ID register probing and init Ben Cheatham
2026-09-23 17:46   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 09/15] cxl/core: Add Cache ID verification Ben Cheatham
2026-09-23 17:49   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 10/15] cxl/core: Add Cache ID allocation Ben Cheatham
2026-09-23 17:49   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 11/15] cxl/core: Add support for HDM-D cache id programming Ben Cheatham
2026-09-23 17:51   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 12/15] cxl/cache: Add snoop filter creation and set up Ben Cheatham
2026-09-23 17:50   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 13/15] cxl/cache: Add snoop filter allocation Ben Cheatham
2026-09-23 17:58   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 14/15] iommu, cxl: Configure IOMMU for CXL.cache Ben Cheatham
2026-09-23 17:57   ` sashiko-bot
2026-09-23 17:33 ` [PATCH 15/15] cxl/cache: Enable CXL.cache on successful probe Ben Cheatham
2026-09-23 17:35 ` [PATCH 00/15] Add initial CXL.cache support Cheatham, Benjamin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260923173342.5584-5-Benjamin.Cheatham@amd.com \
    --to=benjamin.cheatham@amd.com \
    --cc=alison.schofield@intel.com \
    --cc=dave.jiang@intel.com \
    --cc=dave@stgolabs.net \
    --cc=jic23@kernel.org \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linux-iommu@vger.kernel.org \
    --cc=robert.richter@amd.com \
    --cc=terry.bowman@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox