@@ -298,8 +298,7 @@ static int add_host_bridge_uport(struct device *match, void *arg)
return -ENODEV;
}
- port = devm_cxl_add_port(host, match, dport->component_reg_phys,
- root_port);
+ port = devm_cxl_add_port(match, dport->component_reg_phys, root_port);
if (IS_ERR(port))
return PTR_ERR(port);
dev_dbg(host, "%s: add: %s\n", dev_name(match), dev_name(&port->dev));
@@ -467,7 +466,9 @@ static int cxl_acpi_probe(struct platform_device *pdev)
struct device *host = &pdev->dev;
struct acpi_device *adev = ACPI_COMPANION(host);
- root_port = devm_cxl_add_port(host, host, CXL_RESOURCE_NONE, NULL);
+ cxl_register_root(host);
+
+ root_port = devm_cxl_add_port(host, CXL_RESOURCE_NONE, NULL);
if (IS_ERR(root_port))
return PTR_ERR(root_port);
dev_dbg(host, "add: %s\n", dev_name(&root_port->dev));
@@ -513,6 +514,13 @@ static int cxl_acpi_probe(struct platform_device *pdev)
return 0;
}
+static int cxl_acpi_remove(struct platform_device *pdev)
+{
+ cxl_unregister_root();
+
+ return 0;
+}
+
static bool native_acpi0017 = true;
static const struct acpi_device_id cxl_acpi_ids[] = {
@@ -523,6 +531,7 @@ MODULE_DEVICE_TABLE(acpi, cxl_acpi_ids);
static struct platform_driver cxl_acpi_driver = {
.probe = cxl_acpi_probe,
+ .remove = cxl_acpi_remove,
.driver = {
.name = KBUILD_MODNAME,
.acpi_match_table = cxl_acpi_ids,
@@ -27,6 +27,32 @@
static DEFINE_IDA(cxl_port_ida);
static LIST_HEAD(cxl_root_ports);
static DECLARE_RWSEM(root_port_sem);
+static DECLARE_RWSEM(root_host_sem);
+
+static struct device *cxl_root_host;
+
+int cxl_register_root(struct device *host)
+{
+ down_write(&root_host_sem);
+ if (cxl_root_host)
+ return -EBUSY;
+
+ get_device(host);
+ cxl_root_host = host;
+ up_write(&root_host_sem);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxl_register_root);
+
+void cxl_unregister_root(void)
+{
+ down_write(&root_host_sem);
+ put_device(cxl_root_host);
+ cxl_root_host = NULL;
+ up_write(&root_host_sem);
+}
+EXPORT_SYMBOL_GPL(cxl_unregister_root);
static ssize_t devtype_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -375,12 +401,11 @@ static struct cxl_port *cxl_port_alloc(struct device *uport,
/**
* devm_cxl_add_port - register a cxl_port in CXL memory decode hierarchy
- * @host: host device for devm operations
* @uport: "physical" device implementing this upstream port
* @component_reg_phys: (optional) for configurable cxl_port instances
* @parent_port: next hop up in the CXL memory decode hierarchy
*/
-struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
+struct cxl_port *devm_cxl_add_port(struct device *uport,
resource_size_t component_reg_phys,
struct cxl_port *parent_port)
{
@@ -404,11 +429,11 @@ struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
if (rc)
goto err;
- rc = devm_add_action_or_reset(host, unregister_port, port);
+ rc = devm_add_action_or_reset(cxl_root_host, unregister_port, port);
if (rc)
return ERR_PTR(rc);
- rc = devm_cxl_link_uport(host, port);
+ rc = devm_cxl_link_uport(cxl_root_host, port);
if (rc)
return ERR_PTR(rc);
@@ -184,6 +184,9 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
#define CXL_RESOURCE_NONE ((resource_size_t) -1)
#define CXL_TARGET_STRLEN 20
+int cxl_register_root(struct device *host);
+void cxl_unregister_root(void);
+
/*
* cxl_decoder flags that define the type of memory / devices this
* decoder supports as well as configuration lock status See "CXL 2.0
@@ -303,7 +306,7 @@ struct cxl_dport {
};
struct cxl_port *to_cxl_port(struct device *dev);
-struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
+struct cxl_port *devm_cxl_add_port(struct device *uport,
resource_size_t component_reg_phys,
struct cxl_port *parent_port);
Generally, a platform will only have a single instance of an entity which has a platform specific CXL driver. For the time being, this is only the ACPI0017 device defined as part of the CXL specification and ancillary specs (ACPI). With this in mind it becomes easy to drop the need to pass this around for devm functions which want to know the root host. That change allows future work with the mem/port driver to avoid having to determine the root host for port creation for endpoints and switches. There's some technical dept leftover with regard to cxl_test. Signed-off-by: Ben Widawsky <ben.widawsky@intel.com> --- drivers/cxl/acpi.c | 15 ++++++++++++--- drivers/cxl/core/bus.c | 33 +++++++++++++++++++++++++++++---- drivers/cxl/cxl.h | 5 ++++- 3 files changed, 45 insertions(+), 8 deletions(-)