summaryrefslogtreecommitdiff
path: root/drivers/cxl/acpi.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2022-02-01 23:24:30 +0300
committerDan Williams <dan.j.williams@intel.com>2022-02-09 09:57:30 +0300
commitd17d0540a0dbf109210f7b57a37571e2978da0fa (patch)
treed7f969f8c73c1134c480484ebb13a72a2950769e /drivers/cxl/acpi.c
parent98d2d3a264543680281fd8a4e6ae490ca26b4f85 (diff)
downloadlinux-d17d0540a0dbf109210f7b57a37571e2978da0fa.tar.xz
cxl/core/hdm: Add CXL standard decoder enumeration to the core
Unlike the decoder enumeration for "root decoders" described by platform firmware, standard decoders can be enumerated from the component registers space once the base address has been identified (via PCI, ACPI, or another mechanism). Add common infrastructure for HDM (Host-managed-Device-Memory) Decoder enumeration and share it between host-bridge, upstream switch port, and cxl_test defined decoders. The locking model for switch level decoders is to hold the port lock over the enumeration. This facilitates moving the dport and decoder enumeration to a 'port' driver. For now, the only enumerator of decoder resources is the cxl_acpi root driver. Co-developed-by: Ben Widawsky <ben.widawsky@intel.com> Signed-off-by: Ben Widawsky <ben.widawsky@intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Link: https://lore.kernel.org/r/164374688404.395335.9239248252443123526.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/cxl/acpi.c')
-rw-r--r--drivers/cxl/acpi.c43
1 files changed, 15 insertions, 28 deletions
diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
index 259441245687..8c2ced91518b 100644
--- a/drivers/cxl/acpi.c
+++ b/drivers/cxl/acpi.c
@@ -168,10 +168,10 @@ static int add_host_bridge_uport(struct device *match, void *arg)
struct device *host = root_port->dev.parent;
struct acpi_device *bridge = to_cxl_host_bridge(host, match);
struct acpi_pci_root *pci_root;
- int single_port_map[1], rc;
- struct cxl_decoder *cxld;
struct cxl_dport *dport;
+ struct cxl_hdm *cxlhdm;
struct cxl_port *port;
+ int rc;
if (!bridge)
return 0;
@@ -200,37 +200,24 @@ static int add_host_bridge_uport(struct device *match, void *arg)
rc = devm_cxl_port_enumerate_dports(host, port);
if (rc < 0)
return rc;
- if (rc > 1)
- return 0;
-
- /* TODO: Scan CHBCR for HDM Decoder resources */
-
- /*
- * Per the CXL specification (8.2.5.12 CXL HDM Decoder Capability
- * Structure) single ported host-bridges need not publish a decoder
- * capability when a passthrough decode can be assumed, i.e. all
- * transactions that the uport sees are claimed and passed to the single
- * dport. Disable the range until the first CXL region is enumerated /
- * activated.
- */
- cxld = cxl_switch_decoder_alloc(port, 1);
- if (IS_ERR(cxld))
- return PTR_ERR(cxld);
-
cxl_device_lock(&port->dev);
- dport = list_first_entry(&port->dports, typeof(*dport), list);
- cxl_device_unlock(&port->dev);
+ if (rc == 1) {
+ rc = devm_cxl_add_passthrough_decoder(host, port);
+ goto out;
+ }
- single_port_map[0] = dport->port_id;
+ cxlhdm = devm_cxl_setup_hdm(host, port);
+ if (IS_ERR(cxlhdm)) {
+ rc = PTR_ERR(cxlhdm);
+ goto out;
+ }
- rc = cxl_decoder_add(cxld, single_port_map);
+ rc = devm_cxl_enumerate_decoders(host, cxlhdm);
if (rc)
- put_device(&cxld->dev);
- else
- rc = cxl_decoder_autoremove(host, cxld);
+ dev_err(&port->dev, "Couldn't enumerate decoders (%d)\n", rc);
- if (rc == 0)
- dev_dbg(host, "add: %s\n", dev_name(&cxld->dev));
+out:
+ cxl_device_unlock(&port->dev);
return rc;
}