diff options
author | Dan Williams <dan.j.williams@intel.com> | 2022-07-12 18:38:26 -0700 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2022-07-21 08:40:47 -0700 |
commit | 0f157c7fa1a0e1a55b602d8b269344392e9033ad (patch) | |
tree | d4559e85aeb0fb971f726e433c67668b10993188 /drivers/cxl/core | |
parent | 974854ab0728532600c72e41a44d6ce1cf8f20a4 (diff) | |
download | lwn-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.c | 34 |
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); |