mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 23:23:03 +00:00
cxl/core: Define a 'struct cxl_endpoint_decoder'
Previously the target routing specifics of switch decoders and platform CXL window resource tracking of root decoders were factored out of 'struct cxl_decoder'. While switch decoders translate from SPA to downstream ports, endpoint decoders translate from SPA to DPA. This patch, 3 of 3, adds a 'struct cxl_endpoint_decoder' that tracks an endpoint-specific Device Physical Address (DPA) resource. For now this just defines ->dpa_res, a follow-on patch will handle requesting DPA resource ranges from a device-DPA resource tree. 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/165784327088.1758207.15502834501671201192.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
0f157c7fa1
commit
3bf65915ce
@ -256,12 +256,15 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
|
||||
struct cxl_decoder *cxld;
|
||||
|
||||
if (is_cxl_endpoint(port)) {
|
||||
cxld = cxl_endpoint_decoder_alloc(port);
|
||||
if (IS_ERR(cxld)) {
|
||||
struct cxl_endpoint_decoder *cxled;
|
||||
|
||||
cxled = cxl_endpoint_decoder_alloc(port);
|
||||
if (IS_ERR(cxled)) {
|
||||
dev_warn(&port->dev,
|
||||
"Failed to allocate the decoder\n");
|
||||
return PTR_ERR(cxld);
|
||||
return PTR_ERR(cxled);
|
||||
}
|
||||
cxld = &cxled->cxld;
|
||||
} else {
|
||||
struct cxl_switch_decoder *cxlsd;
|
||||
|
||||
|
@ -244,12 +244,12 @@ static void __cxl_decoder_release(struct cxl_decoder *cxld)
|
||||
put_device(&port->dev);
|
||||
}
|
||||
|
||||
static void cxl_decoder_release(struct device *dev)
|
||||
static void cxl_endpoint_decoder_release(struct device *dev)
|
||||
{
|
||||
struct cxl_decoder *cxld = to_cxl_decoder(dev);
|
||||
struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
|
||||
|
||||
__cxl_decoder_release(cxld);
|
||||
kfree(cxld);
|
||||
__cxl_decoder_release(&cxled->cxld);
|
||||
kfree(cxled);
|
||||
}
|
||||
|
||||
static void cxl_switch_decoder_release(struct device *dev)
|
||||
@ -279,7 +279,7 @@ static void cxl_root_decoder_release(struct device *dev)
|
||||
|
||||
static const struct device_type cxl_decoder_endpoint_type = {
|
||||
.name = "cxl_decoder_endpoint",
|
||||
.release = cxl_decoder_release,
|
||||
.release = cxl_endpoint_decoder_release,
|
||||
.groups = cxl_decoder_endpoint_attribute_groups,
|
||||
};
|
||||
|
||||
@ -321,6 +321,15 @@ struct cxl_decoder *to_cxl_decoder(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(to_cxl_decoder, CXL);
|
||||
|
||||
struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev)
|
||||
{
|
||||
if (dev_WARN_ONCE(dev, !is_endpoint_decoder(dev),
|
||||
"not a cxl_endpoint_decoder device\n"))
|
||||
return NULL;
|
||||
return container_of(dev, struct cxl_endpoint_decoder, cxld.dev);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(to_cxl_endpoint_decoder, CXL);
|
||||
|
||||
static struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev)
|
||||
{
|
||||
if (dev_WARN_ONCE(dev, !is_switch_decoder(dev),
|
||||
@ -1360,26 +1369,28 @@ EXPORT_SYMBOL_NS_GPL(cxl_switch_decoder_alloc, CXL);
|
||||
*
|
||||
* Return: A new cxl decoder to be registered by cxl_decoder_add()
|
||||
*/
|
||||
struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
|
||||
struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
|
||||
{
|
||||
struct cxl_endpoint_decoder *cxled;
|
||||
struct cxl_decoder *cxld;
|
||||
int rc;
|
||||
|
||||
if (!is_cxl_endpoint(port))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
cxld = kzalloc(sizeof(*cxld), GFP_KERNEL);
|
||||
if (!cxld)
|
||||
cxled = kzalloc(sizeof(*cxled), GFP_KERNEL);
|
||||
if (!cxled)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
cxld = &cxled->cxld;
|
||||
rc = cxl_decoder_init(port, cxld);
|
||||
if (rc) {
|
||||
kfree(cxld);
|
||||
kfree(cxled);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
cxld->dev.type = &cxl_decoder_endpoint_type;
|
||||
return cxld;
|
||||
return cxled;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_alloc, CXL);
|
||||
|
||||
|
@ -239,6 +239,18 @@ struct cxl_decoder {
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cxl_endpoint_decoder - Endpoint / SPA to DPA decoder
|
||||
* @cxld: base cxl_decoder_object
|
||||
* @dpa_res: actively claimed DPA span of this decoder
|
||||
* @skip: offset into @dpa_res where @cxld.hpa_range maps
|
||||
*/
|
||||
struct cxl_endpoint_decoder {
|
||||
struct cxl_decoder cxld;
|
||||
struct resource *dpa_res;
|
||||
resource_size_t skip;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cxl_switch_decoder - Switch specific CXL HDM Decoder
|
||||
* @cxld: base cxl_decoder object
|
||||
@ -394,6 +406,7 @@ struct cxl_dport *cxl_find_dport_by_dev(struct cxl_port *port,
|
||||
|
||||
struct cxl_decoder *to_cxl_decoder(struct device *dev);
|
||||
struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev);
|
||||
struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev);
|
||||
bool is_root_decoder(struct device *dev);
|
||||
bool is_endpoint_decoder(struct device *dev);
|
||||
struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
|
||||
@ -401,7 +414,7 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
|
||||
struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port,
|
||||
unsigned int nr_targets);
|
||||
int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);
|
||||
struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
|
||||
struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
|
||||
int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map);
|
||||
int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld);
|
||||
int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint);
|
||||
|
@ -462,12 +462,16 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
|
||||
}
|
||||
cxld = &cxlsd->cxld;
|
||||
} else {
|
||||
cxld = cxl_endpoint_decoder_alloc(port);
|
||||
if (IS_ERR(cxld)) {
|
||||
struct cxl_endpoint_decoder *cxled;
|
||||
|
||||
cxled = cxl_endpoint_decoder_alloc(port);
|
||||
|
||||
if (IS_ERR(cxled)) {
|
||||
dev_warn(&port->dev,
|
||||
"Failed to allocate the decoder\n");
|
||||
return PTR_ERR(cxld);
|
||||
return PTR_ERR(cxled);
|
||||
}
|
||||
cxld = &cxled->cxld;
|
||||
}
|
||||
|
||||
cxld->hpa_range = (struct range) {
|
||||
|
Loading…
Reference in New Issue
Block a user