summaryrefslogtreecommitdiff
path: root/drivers/cxl/core
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2022-07-12 18:38:26 -0700
committerDan Williams <dan.j.williams@intel.com>2022-07-21 08:40:47 -0700
commit0f157c7fa1a0e1a55b602d8b269344392e9033ad (patch)
treed4559e85aeb0fb971f726e433c67668b10993188 /drivers/cxl/core
parent974854ab0728532600c72e41a44d6ce1cf8f20a4 (diff)
downloadlwn-0f157c7fa1a0e1a55b602d8b269344392e9033ad.tar.gz
lwn-0f157c7fa1a0e1a55b602d8b269344392e9033ad.zip
cxl/core: Define a 'struct cxl_root_decoder'
Previously the target routing specifics of switch decoders were factored out of 'struct cxl_decoder' into 'struct cxl_switch_decoder'. This patch, 2 of 3, adds a 'struct cxl_root_decoder' as a superset of a switch decoder that also track the associated CXL window platform resource. Note that the reason the resource for a given root decoder needs to be looked up after the fact (i.e. after cxl_parse_cfmws() and add_cxl_resource()) is because add_cxl_resource() may have merged CXL windows in order to keep them at the top of the resource tree / decode hierarchy. Co-developed-by: Ben Widawsky <bwidawsk@kernel.org> Signed-off-by: Ben Widawsky <bwidawsk@kernel.org> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Link: https://lore.kernel.org/r/165784326541.1758207.9915663937394448341.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/cxl/core')
-rw-r--r--drivers/cxl/core/port.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 3ce7a1b023d5..972bca7e3370 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -260,6 +260,23 @@ static void cxl_switch_decoder_release(struct device *dev)
kfree(cxlsd);
}
+struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev)
+{
+ if (dev_WARN_ONCE(dev, !is_root_decoder(dev),
+ "not a cxl_root_decoder device\n"))
+ return NULL;
+ return container_of(dev, struct cxl_root_decoder, cxlsd.cxld.dev);
+}
+EXPORT_SYMBOL_NS_GPL(to_cxl_root_decoder, CXL);
+
+static void cxl_root_decoder_release(struct device *dev)
+{
+ struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
+
+ __cxl_decoder_release(&cxlrd->cxlsd.cxld);
+ kfree(cxlrd);
+}
+
static const struct device_type cxl_decoder_endpoint_type = {
.name = "cxl_decoder_endpoint",
.release = cxl_decoder_release,
@@ -274,7 +291,7 @@ static const struct device_type cxl_decoder_switch_type = {
static const struct device_type cxl_decoder_root_type = {
.name = "cxl_decoder_root",
- .release = cxl_switch_decoder_release,
+ .release = cxl_root_decoder_release,
.groups = cxl_decoder_root_attribute_groups,
};
@@ -1271,9 +1288,10 @@ static int cxl_switch_decoder_init(struct cxl_port *port,
* firmware description of CXL resources into a CXL standard decode
* topology.
*/
-struct cxl_switch_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
- unsigned int nr_targets)
+struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
+ unsigned int nr_targets)
{
+ struct cxl_root_decoder *cxlrd;
struct cxl_switch_decoder *cxlsd;
struct cxl_decoder *cxld;
int rc;
@@ -1281,19 +1299,21 @@ struct cxl_switch_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
if (!is_cxl_root(port))
return ERR_PTR(-EINVAL);
- cxlsd = kzalloc(struct_size(cxlsd, target, nr_targets), GFP_KERNEL);
- if (!cxlsd)
+ cxlrd = kzalloc(struct_size(cxlrd, cxlsd.target, nr_targets),
+ GFP_KERNEL);
+ if (!cxlrd)
return ERR_PTR(-ENOMEM);
+ cxlsd = &cxlrd->cxlsd;
rc = cxl_switch_decoder_init(port, cxlsd, nr_targets);
if (rc) {
- kfree(cxlsd);
+ kfree(cxlrd);
return ERR_PTR(rc);
}
cxld = &cxlsd->cxld;
cxld->dev.type = &cxl_decoder_root_type;
- return cxlsd;
+ return cxlrd;
}
EXPORT_SYMBOL_NS_GPL(cxl_root_decoder_alloc, CXL);