Skip to content

Commit 68d8b4f

Browse files
committed
Merge branch 'for-6.16/cxl-cleanups' into cxl-for-next
In preparation for code changes related to AMD Zen5 address translation support, a number of small code refactor and cleanups are send ahead.
2 parents 8e62ba5 + 98a863f commit 68d8b4f

File tree

9 files changed

+173
-122
lines changed

9 files changed

+173
-122
lines changed

drivers/cxl/acpi.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,15 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
419419
rc = cxl_decoder_add(cxld, target_map);
420420
if (rc)
421421
return rc;
422-
return cxl_root_decoder_autoremove(dev, no_free_ptr(cxlrd));
422+
423+
rc = cxl_root_decoder_autoremove(dev, no_free_ptr(cxlrd));
424+
if (rc)
425+
return rc;
426+
427+
dev_dbg(root_port->dev.parent, "%s added to %s\n",
428+
dev_name(&cxld->dev), dev_name(&root_port->dev));
429+
430+
return 0;
423431
}
424432

425433
static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,

drivers/cxl/core/cdat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static u32 cdat_normalize(u16 entry, u64 base, u8 type)
2828
*/
2929
if (entry == 0xffff || !entry)
3030
return 0;
31-
else if (base > (UINT_MAX / (entry)))
31+
if (base > (UINT_MAX / (entry)))
3232
return 0;
3333

3434
/*

drivers/cxl/core/hdm.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
3434
if (rc)
3535
return rc;
3636

37-
dev_dbg(&cxld->dev, "Added to port %s\n", dev_name(&port->dev));
37+
dev_dbg(port->uport_dev, "%s added to %s\n",
38+
dev_name(&cxld->dev), dev_name(&port->dev));
3839

3940
return 0;
4041
}

drivers/cxl/core/memdev.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ static ssize_t security_state_show(struct device *dev,
153153
return sysfs_emit(buf, "frozen\n");
154154
if (state & CXL_PMEM_SEC_STATE_LOCKED)
155155
return sysfs_emit(buf, "locked\n");
156-
else
157-
return sysfs_emit(buf, "unlocked\n");
156+
157+
return sysfs_emit(buf, "unlocked\n");
158158
}
159159
static struct device_attribute dev_attr_security_state =
160160
__ATTR(state, 0444, security_state_show, NULL);

drivers/cxl/core/pci.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -415,17 +415,20 @@ int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
415415
*/
416416
if (global_ctrl & CXL_HDM_DECODER_ENABLE || (!hdm && info->mem_enabled))
417417
return devm_cxl_enable_mem(&port->dev, cxlds);
418-
else if (!hdm)
419-
return -ENODEV;
420418

421-
root = to_cxl_port(port->dev.parent);
422-
while (!is_cxl_root(root) && is_cxl_port(root->dev.parent))
423-
root = to_cxl_port(root->dev.parent);
424-
if (!is_cxl_root(root)) {
425-
dev_err(dev, "Failed to acquire root port for HDM enable\n");
419+
/*
420+
* If the HDM Decoder Capability does not exist and DVSEC was
421+
* not setup, the DVSEC based emulation cannot be used.
422+
*/
423+
if (!hdm)
426424
return -ENODEV;
427-
}
428425

426+
/* The HDM Decoder Capability exists but is globally disabled. */
427+
428+
/*
429+
* If the DVSEC CXL Range registers are not enabled, just
430+
* enable and use the HDM Decoder Capability registers.
431+
*/
429432
if (!info->mem_enabled) {
430433
rc = devm_cxl_enable_hdm(&port->dev, cxlhdm);
431434
if (rc)
@@ -434,6 +437,26 @@ int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
434437
return devm_cxl_enable_mem(&port->dev, cxlds);
435438
}
436439

440+
/*
441+
* Per CXL 2.0 Section 8.1.3.8.3 and 8.1.3.8.4 DVSEC CXL Range 1 Base
442+
* [High,Low] when HDM operation is enabled the range register values
443+
* are ignored by the device, but the spec also recommends matching the
444+
* DVSEC Range 1,2 to HDM Decoder Range 0,1. So, non-zero info->ranges
445+
* are expected even though Linux does not require or maintain that
446+
* match. Check if at least one DVSEC range is enabled and allowed by
447+
* the platform. That is, the DVSEC range must be covered by a locked
448+
* platform window (CFMWS). Fail otherwise as the endpoint's decoders
449+
* cannot be used.
450+
*/
451+
452+
root = to_cxl_port(port->dev.parent);
453+
while (!is_cxl_root(root) && is_cxl_port(root->dev.parent))
454+
root = to_cxl_port(root->dev.parent);
455+
if (!is_cxl_root(root)) {
456+
dev_err(dev, "Failed to acquire root port for HDM enable\n");
457+
return -ENODEV;
458+
}
459+
437460
for (i = 0, allowed = 0; i < info->ranges; i++) {
438461
struct device *cxld_dev;
439462

@@ -453,15 +476,6 @@ int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
453476
return -ENXIO;
454477
}
455478

456-
/*
457-
* Per CXL 2.0 Section 8.1.3.8.3 and 8.1.3.8.4 DVSEC CXL Range 1 Base
458-
* [High,Low] when HDM operation is enabled the range register values
459-
* are ignored by the device, but the spec also recommends matching the
460-
* DVSEC Range 1,2 to HDM Decoder Range 0,1. So, non-zero info->ranges
461-
* are expected even though Linux does not require or maintain that
462-
* match. If at least one DVSEC range is enabled and allowed, skip HDM
463-
* Decoder Capability Enable.
464-
*/
465479
return 0;
466480
}
467481
EXPORT_SYMBOL_NS_GPL(cxl_hdm_decode_init, "CXL");

drivers/cxl/core/port.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -602,17 +602,19 @@ struct cxl_port *to_cxl_port(const struct device *dev)
602602
}
603603
EXPORT_SYMBOL_NS_GPL(to_cxl_port, "CXL");
604604

605+
struct cxl_port *parent_port_of(struct cxl_port *port)
606+
{
607+
if (!port || !port->parent_dport)
608+
return NULL;
609+
return port->parent_dport->port;
610+
}
611+
605612
static void unregister_port(void *_port)
606613
{
607614
struct cxl_port *port = _port;
608-
struct cxl_port *parent;
615+
struct cxl_port *parent = parent_port_of(port);
609616
struct device *lock_dev;
610617

611-
if (is_cxl_root(port))
612-
parent = NULL;
613-
else
614-
parent = to_cxl_port(port->dev.parent);
615-
616618
/*
617619
* CXL root port's and the first level of ports are unregistered
618620
* under the platform firmware device lock, all other ports are
@@ -1035,15 +1037,6 @@ struct cxl_root *find_cxl_root(struct cxl_port *port)
10351037
}
10361038
EXPORT_SYMBOL_NS_GPL(find_cxl_root, "CXL");
10371039

1038-
void put_cxl_root(struct cxl_root *cxl_root)
1039-
{
1040-
if (!cxl_root)
1041-
return;
1042-
1043-
put_device(&cxl_root->port.dev);
1044-
}
1045-
EXPORT_SYMBOL_NS_GPL(put_cxl_root, "CXL");
1046-
10471040
static struct cxl_dport *find_dport(struct cxl_port *port, int id)
10481041
{
10491042
struct cxl_dport *dport;

0 commit comments

Comments
 (0)