Skip to content

Commit

Permalink
cxl/region: Prepare the decoder match range helper for reuse
Browse files Browse the repository at this point in the history
match_decoder_by_range() and decoder_match_range() both determine
if an HPA range matches a decoder. The first does it for root
decoders and the second one operates on switch decoders.

Tidy these up with clear naming and make the switch helper more
like the root decoder helper in style and functionality. Make it
take the actual range, rather than an endpoint decoder from which
it extracts the range. Require an exact match on switch decoders,
because unlike a root decoder that maps an entire region, Linux
only supports 1:1 mapping of switch to endpoint decoders. Note that
root-decoders are a super-set of switch-decoders and the range they
cover is a super-set of a region, hence the use of range_contains() for
that case.

Aside from aesthetics and maintainability, this is in preparation
for reuse.

Signed-off-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Jim Harris <jim.harris@samsung.com>
Link: https://lore.kernel.org/r/011b1f498e1758bb8df17c5951be00bd8d489e3b.1698263080.git.alison.schofield@intel.com
[djbw: fixup root decoder vs switch decoder range checks]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
AlisonSchofield authored and djbw committed Oct 26, 2023
1 parent 0718588 commit 1110581
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions drivers/cxl/core/region.c
Original file line number Diff line number Diff line change
Expand Up @@ -1481,16 +1481,20 @@ static struct cxl_port *next_port(struct cxl_port *port)
return port->parent_dport->port;
}

static int decoder_match_range(struct device *dev, void *data)
static int match_switch_decoder_by_range(struct device *dev, void *data)
{
struct cxl_endpoint_decoder *cxled = data;
struct cxl_switch_decoder *cxlsd;
struct range *r1, *r2 = data;

if (!is_switch_decoder(dev))
return 0;

cxlsd = to_cxl_switch_decoder(dev);
return range_contains(&cxlsd->cxld.hpa_range, &cxled->cxld.hpa_range);
r1 = &cxlsd->cxld.hpa_range;

if (is_root_decoder(dev))
return range_contains(r1, r2);
return (r1->start == r2->start && r1->end == r2->end);
}

static void find_positions(const struct cxl_switch_decoder *cxlsd,
Expand Down Expand Up @@ -1559,7 +1563,8 @@ static int cmp_decode_pos(const void *a, const void *b)
goto err;
}

dev = device_find_child(&port->dev, cxled_a, decoder_match_range);
dev = device_find_child(&port->dev, &cxled_a->cxld.hpa_range,
match_switch_decoder_by_range);
if (!dev) {
struct range *range = &cxled_a->cxld.hpa_range;

Expand Down Expand Up @@ -2690,7 +2695,7 @@ static int devm_cxl_add_dax_region(struct cxl_region *cxlr)
return rc;
}

static int match_decoder_by_range(struct device *dev, void *data)
static int match_root_decoder_by_range(struct device *dev, void *data)
{
struct range *r1, *r2 = data;
struct cxl_root_decoder *cxlrd;
Expand Down Expand Up @@ -2821,7 +2826,7 @@ int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled)
int rc;

cxlrd_dev = device_find_child(&root->dev, &cxld->hpa_range,
match_decoder_by_range);
match_root_decoder_by_range);
if (!cxlrd_dev) {
dev_err(cxlmd->dev.parent,
"%s:%s no CXL window for range %#llx:%#llx\n",
Expand Down

0 comments on commit 1110581

Please sign in to comment.