Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cxl/region: Move HPA setup to cxl_region_attach()

A recent bug fix added the setup of the endpoint decoder interleave
geometry settings to cxl_region_attach(). Move the HPA setup there as
well to keep all endpoint decoder parameter setting in a central
location.

For symmetry, move endpoint HPA teardown to cxl_region_detach(), and for
switches move HPA setup / teardown to cxl_port_{setup,reset}_targets().

Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Link: https://lore.kernel.org/r/165973126020.1526540.14701949254436069807.stgit@dwillia2-xfh.jf.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

+24 -26
+2 -24
drivers/cxl/core/hdm.c
··· 499 499 CXL_HDM_DECODER0_CTRL_TYPE); 500 500 } 501 501 502 - static void cxld_set_hpa(struct cxl_decoder *cxld, u64 *base, u64 *size) 503 - { 504 - struct cxl_region *cxlr = cxld->region; 505 - struct cxl_region_params *p = &cxlr->params; 506 - 507 - cxld->hpa_range = (struct range) { 508 - .start = p->res->start, 509 - .end = p->res->end, 510 - }; 511 - 512 - *base = p->res->start; 513 - *size = resource_size(p->res); 514 - } 515 - 516 - static void cxld_clear_hpa(struct cxl_decoder *cxld) 517 - { 518 - cxld->hpa_range = (struct range) { 519 - .start = 0, 520 - .end = -1, 521 - }; 522 - } 523 - 524 502 static int cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt) 525 503 { 526 504 struct cxl_dport **t = &cxlsd->target[0]; ··· 579 601 ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id)); 580 602 cxld_set_interleave(cxld, &ctrl); 581 603 cxld_set_type(cxld, &ctrl); 582 - cxld_set_hpa(cxld, &base, &size); 604 + base = cxld->hpa_range.start; 605 + size = range_len(&cxld->hpa_range); 583 606 584 607 writel(upper_32_bits(base), hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(id)); 585 608 writel(lower_32_bits(base), hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id)); ··· 653 674 ctrl &= ~CXL_HDM_DECODER0_CTRL_COMMIT; 654 675 writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id)); 655 676 656 - cxld_clear_hpa(cxld); 657 677 writel(0, hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(id)); 658 678 writel(0, hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(id)); 659 679 writel(0, hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(id));
+22 -2
drivers/cxl/core/region.c
··· 1044 1044 1045 1045 cxld->interleave_ways = iw; 1046 1046 cxld->interleave_granularity = ig; 1047 + cxld->hpa_range = (struct range) { 1048 + .start = p->res->start, 1049 + .end = p->res->end, 1050 + }; 1047 1051 dev_dbg(&cxlr->dev, "%s:%s iw: %d ig: %d\n", dev_name(port->uport), 1048 1052 dev_name(&port->dev), iw, ig); 1049 1053 add_target: ··· 1074 1070 struct cxl_region *cxlr) 1075 1071 { 1076 1072 struct cxl_region_ref *cxl_rr = cxl_rr_load(port, cxlr); 1073 + struct cxl_decoder *cxld; 1077 1074 1078 1075 /* 1079 1076 * After the last endpoint has been detached the entire cxl_rr may now 1080 1077 * be gone. 1081 1078 */ 1082 - if (cxl_rr) 1083 - cxl_rr->nr_targets_set = 0; 1079 + if (!cxl_rr) 1080 + return; 1081 + cxl_rr->nr_targets_set = 0; 1082 + 1083 + cxld = cxl_rr->decoder; 1084 + cxld->hpa_range = (struct range) { 1085 + .start = 0, 1086 + .end = -1, 1087 + }; 1084 1088 } 1085 1089 1086 1090 static void cxl_region_teardown_targets(struct cxl_region *cxlr) ··· 1269 1257 1270 1258 cxled->cxld.interleave_ways = p->interleave_ways; 1271 1259 cxled->cxld.interleave_granularity = p->interleave_granularity; 1260 + cxled->cxld.hpa_range = (struct range) { 1261 + .start = p->res->start, 1262 + .end = p->res->end, 1263 + }; 1272 1264 1273 1265 return 0; 1274 1266 ··· 1331 1315 } 1332 1316 p->targets[cxled->pos] = NULL; 1333 1317 p->nr_targets--; 1318 + cxled->cxld.hpa_range = (struct range) { 1319 + .start = 0, 1320 + .end = -1, 1321 + }; 1334 1322 1335 1323 /* notify the region driver that one of its targets has departed */ 1336 1324 up_write(&cxl_region_rwsem);