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
next prev 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.