diff mbox series

[8/8] cxl/acpi: Add module parameters to stand in for ACPI tables

Message ID 162042792370.1202325.11876776878497740843.stgit@dwillia2-desk3.amr.corp.intel.com
State Superseded
Headers show
Series CXL Port Enumeration and Plans for v5.14 | expand

Commit Message

Dan Williams May 7, 2021, 10:52 p.m. UTC
[debug / to-be-replaced / not-for-upstream]

Given ACPICA support is needed before drivers can integrate ACPI
functionality add some module parameters as proxies.
---
 drivers/cxl/acpi.c |   81 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
index bc2a35ae880b..2a48a728f3e0 100644
--- a/drivers/cxl/acpi.c
+++ b/drivers/cxl/acpi.c
@@ -4,10 +4,84 @@ 
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/range.h>
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include "cxl.h"
 
+/*
+ * TODO: Replace all of the below module parameters with ACPI CXL
+ * resource descriptions once ACPICA makes them available.
+ */
+static unsigned long chbcr[4];
+module_param_named(chbcr0, chbcr[0], ulong, 0400);
+module_param_named(chbcr1, chbcr[1], ulong, 0400);
+module_param_named(chbcr2, chbcr[2], ulong, 0400);
+module_param_named(chbcr3, chbcr[3], ulong, 0400);
+
+/* TODO: cross-bridge interleave */
+static struct cxl_address_space cxl_space[] = {
+	[0] = { .range = { 0, -1 }, .targets = 0x1, },
+	[1] = { .range = { 0, -1 }, .targets = 0x1, },
+	[2] = { .range = { 0, -1 }, .targets = 0x1, },
+	[3] = { .range = { 0, -1 }, .targets = 0x1, },
+};
+
+static int set_range(const char *val, const struct kernel_param *kp)
+{
+	unsigned long long size, base;
+	struct cxl_address_space *space;
+	unsigned long flags;
+	char *p;
+	int rc;
+
+	size = memparse(val, &p);
+	if (*p != '@')
+		return -EINVAL;
+
+	base = memparse(p + 1, &p);
+	if (*p != ':')
+		return -EINVAL;
+
+	rc = kstrtoul(p + 1, 0, &flags);
+	if (rc)
+		return rc;
+	if (!flags || flags > CXL_ADDRSPACE_MASK)
+		return rc;
+
+	space = kp->arg;
+	*space = (struct cxl_address_space) {
+		.range = {
+			.start = base,
+			.end = base + size - 1,
+		},
+		.flags = flags,
+	};
+
+	return 0;
+}
+
+static int get_range(char *buf, const struct kernel_param *kp)
+{
+	struct cxl_address_space *space = kp->arg;
+
+	if (!range_len(&space->range))
+		return -EINVAL;
+
+	return sysfs_emit(buf, "%#llx@%#llx :%s%s%s%s\n",
+			  (unsigned long long)range_len(&space->range),
+			  (unsigned long long)space->range.start,
+			  space->flags & CXL_ADDRSPACE_RAM ? " ram" : "",
+			  space->flags & CXL_ADDRSPACE_PMEM ? " pmem" : "",
+			  space->flags & CXL_ADDRSPACE_TYPE2 ? " type2" : "",
+			  space->flags & CXL_ADDRSPACE_TYPE3 ? " type3" : "");
+}
+
+module_param_call(range0, set_range, get_range, &cxl_space[0], 0400);
+module_param_call(range1, set_range, get_range, &cxl_space[1], 0400);
+module_param_call(range2, set_range, get_range, &cxl_space[2], 0400);
+module_param_call(range3, set_range, get_range, &cxl_space[3], 0400);
+
 static int match_ACPI0016(struct device *dev, const void *host)
 {
 	struct acpi_device *adev = to_acpi_device(dev);
@@ -67,13 +141,16 @@  static int cxl_acpi_register_ports(struct device *dev, struct acpi_device *root,
 				   struct cxl_port *port, int idx)
 {
 	struct acpi_pci_root *pci_root = acpi_pci_find_root(root->handle);
+	resource_size_t chbcr_base = ~0ULL;
 	struct cxl_walk_context ctx;
 
 	if (!pci_root)
 		return -ENXIO;
 
 	/* TODO: fold in CEDT.CHBS retrieval */
-	port = devm_cxl_add_port(dev, port, &root->dev, idx, ~0ULL);
+	if (idx < ARRAY_SIZE(chbcr))
+		chbcr_base = chbcr[idx];
+	port = devm_cxl_add_port(dev, port, &root->dev, idx, chbcr_base);
 	if (IS_ERR(port))
 		return PTR_ERR(port);
 	dev_dbg(dev, "%s: register: %s\n", dev_name(&root->dev),
@@ -99,7 +176,7 @@  static int cxl_acpi_probe(struct platform_device *pdev)
 	struct cxl_root *cxl_root;
 	int rc, i = 0;
 
-	cxl_root = devm_cxl_add_root(dev, NULL, 0);
+	cxl_root = devm_cxl_add_root(dev, cxl_space, ARRAY_SIZE(cxl_space));
 	if (IS_ERR(cxl_root))
 		return PTR_ERR(cxl_root);
 	dev_dbg(dev, "register: %s\n", dev_name(&cxl_root->port.dev));