]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cxl/port: Move dport RAS setup to dport add time
authorDan Williams <dan.j.williams@intel.com>
Sat, 31 Jan 2026 00:04:00 +0000 (16:04 -0800)
committerDave Jiang <dave.jiang@intel.com>
Mon, 2 Feb 2026 15:44:51 +0000 (08:44 -0700)
Towards the end goal of making all CXL RAS capability handling uniform
across host bridge ports, upstream switch ports, and endpoint ports, move
dport RAS setup. Move it to cxl_switch_port_probe() context for switch / VH
dports (via cxl_port_add_dport()) and cxl_endpoint_port_probe() context for
an RCH dport. Rename the RAS setup helper to devm_cxl_dport_ras_setup() for
symmetry with devm_cxl_switch_port_decoders_setup().

Only the RCH version needs to be exported and the cxl_test mocking can be
deleted with a dev_is_pci() check on the dport_dev.

Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Tested-by: Terry Bowman <terry.bowman@amd.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Link: https://patch.msgid.link/20260131000403.2135324-7-dan.j.williams@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/core/core.h
drivers/cxl/core/port.c
drivers/cxl/core/ras.c
drivers/cxl/cxlpci.h
drivers/cxl/mem.c
drivers/cxl/port.c
tools/testing/cxl/Kbuild
tools/testing/cxl/test/mock.c

index 422531799af2fadc4943305ea58a1af3500a3c66..be3c7b1371157101fbb5617b95fc64c064b3d6a1 100644 (file)
@@ -144,6 +144,14 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c);
 int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port,
                                        struct access_coordinate *c);
 
+static inline struct device *dport_to_host(struct cxl_dport *dport)
+{
+       struct cxl_port *port = dport->port;
+
+       if (is_cxl_root(port))
+               return port->uport_dev;
+       return &port->dev;
+}
 #ifdef CONFIG_CXL_RAS
 int cxl_ras_init(void);
 void cxl_ras_exit(void);
@@ -152,6 +160,7 @@ void cxl_handle_cor_ras(struct device *dev, void __iomem *ras_base);
 void cxl_dport_map_rch_aer(struct cxl_dport *dport);
 void cxl_disable_rch_root_ints(struct cxl_dport *dport);
 void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds);
+void devm_cxl_dport_ras_setup(struct cxl_dport *dport);
 #else
 static inline int cxl_ras_init(void)
 {
@@ -166,6 +175,7 @@ static inline void cxl_handle_cor_ras(struct device *dev, void __iomem *ras_base
 static inline void cxl_dport_map_rch_aer(struct cxl_dport *dport) { }
 static inline void cxl_disable_rch_root_ints(struct cxl_dport *dport) { }
 static inline void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds) { }
+static inline void devm_cxl_dport_ras_setup(struct cxl_dport *dport) { }
 #endif /* CONFIG_CXL_RAS */
 
 int cxl_gpf_port_setup(struct cxl_dport *dport);
index 7356e1725db8f4eeb7ac76d35fe2a35db0b693fe..9f56f7e75e81c1d181e7bc4619973479936ba7c8 100644 (file)
@@ -1119,15 +1119,6 @@ static void cxl_dport_unlink(void *data)
        sysfs_remove_link(&port->dev.kobj, link_name);
 }
 
-static struct device *dport_to_host(struct cxl_dport *dport)
-{
-       struct cxl_port *port = dport->port;
-
-       if (is_cxl_root(port))
-               return port->uport_dev;
-       return &port->dev;
-}
-
 static void free_dport(void *dport)
 {
        kfree(dport);
@@ -1261,6 +1252,9 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
 
        cxl_debugfs_create_dport_dir(dport);
 
+       if (!dport->rch)
+               devm_cxl_dport_ras_setup(dport);
+
        /* keep the group, and mark the end of devm actions */
        cxl_dport_close_dr_group(dport, no_free_ptr(dport_dr_group));
 
index 72908f3ced775c89e8b8c77d31639c99dcb4a1bb..e90b7a91bf5de92d93da9d283df1106593bd0f88 100644 (file)
@@ -139,26 +139,32 @@ static void cxl_dport_map_ras(struct cxl_dport *dport)
 }
 
 /**
- * cxl_dport_init_ras_reporting - Setup CXL RAS report on this dport
+ * devm_cxl_dport_ras_setup - Setup CXL RAS report on this dport
  * @dport: the cxl_dport that needs to be initialized
- * @host: host device for devm operations
  */
-void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
+void devm_cxl_dport_ras_setup(struct cxl_dport *dport)
 {
-       dport->reg_map.host = host;
+       dport->reg_map.host = dport_to_host(dport);
        cxl_dport_map_ras(dport);
+}
 
-       if (dport->rch) {
-               struct pci_host_bridge *host_bridge = to_pci_host_bridge(dport->dport_dev);
+void devm_cxl_dport_rch_ras_setup(struct cxl_dport *dport)
+{
+       struct pci_host_bridge *host_bridge;
 
-               if (!host_bridge->native_aer)
-                       return;
+       if (!dev_is_pci(dport->dport_dev))
+               return;
 
-               cxl_dport_map_rch_aer(dport);
-               cxl_disable_rch_root_ints(dport);
-       }
+       devm_cxl_dport_ras_setup(dport);
+
+       host_bridge = to_pci_host_bridge(dport->dport_dev);
+       if (!host_bridge->native_aer)
+               return;
+
+       cxl_dport_map_rch_aer(dport);
+       cxl_disable_rch_root_ints(dport);
 }
-EXPORT_SYMBOL_NS_GPL(cxl_dport_init_ras_reporting, "CXL");
+EXPORT_SYMBOL_NS_GPL(devm_cxl_dport_rch_ras_setup, "CXL");
 
 void cxl_handle_cor_ras(struct device *dev, void __iomem *ras_base)
 {
index 6f9c78886fd9a822cc0a8b905ac28933521e8c2e..65575371a35c9540cf8154d1bd61a4c6e891ee60 100644 (file)
@@ -81,7 +81,7 @@ void read_cdat_data(struct cxl_port *port);
 void cxl_cor_error_detected(struct pci_dev *pdev);
 pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
                                    pci_channel_state_t state);
-void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host);
+void devm_cxl_dport_rch_ras_setup(struct cxl_dport *dport);
 #else
 static inline void cxl_cor_error_detected(struct pci_dev *pdev) { }
 
@@ -91,8 +91,9 @@ static inline pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
        return PCI_ERS_RESULT_NONE;
 }
 
-static inline void cxl_dport_init_ras_reporting(struct cxl_dport *dport,
-                                               struct device *host) { }
+static inline void devm_cxl_dport_rch_ras_setup(struct cxl_dport *dport)
+{
+}
 #endif
 
 #endif /* __CXL_PCI_H__ */
index c2ee7f7f6320b5f5a280e29473d1fc565f546297..e25c33f8c6cf8e01ba987d72bbe485e5153fea52 100644 (file)
@@ -166,8 +166,6 @@ static int cxl_mem_probe(struct device *dev)
        else
                endpoint_parent = &parent_port->dev;
 
-       cxl_dport_init_ras_reporting(dport, dev);
-
        scoped_guard(device, endpoint_parent) {
                if (!endpoint_parent->driver) {
                        dev_err(dev, "CXL port topology %s not enabled\n",
index 913c469e067a16c0a8b9d80a19b06d08ffab0ff3..929f7e259f0d3f29825b7a571a03ade4eee1c2ad 100644 (file)
@@ -71,6 +71,7 @@ static int cxl_switch_port_probe(struct cxl_port *port)
 static int cxl_endpoint_port_probe(struct cxl_port *port)
 {
        struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
+       struct cxl_dport *dport = port->parent_dport;
        int rc;
 
        /* Cache the data early to ensure is_visible() works */
@@ -86,6 +87,17 @@ static int cxl_endpoint_port_probe(struct cxl_port *port)
        if (rc)
                return rc;
 
+       /*
+        * With VH (CXL Virtual Host) topology the cxl_port::add_dport() method
+        * handles RAS setup for downstream ports. With RCH (CXL Restricted CXL
+        * Host) topologies the downstream port is enumerated early by platform
+        * firmware, but the RCRB (root complex register block) is not mapped
+        * until after the cxl_pci driver attaches to the RCIeP (root complex
+        * integrated endpoint).
+        */
+       if (dport->rch)
+               devm_cxl_dport_rch_ras_setup(dport);
+
        /*
         * Now that all endpoint decoders are successfully enumerated, try to
         * assemble regions from committed decoders
index 9b2d514a867e160d451ebab6b23b36eeff310e0d..982e8ea28b92443b74356b099e208b8525767921 100644 (file)
@@ -7,7 +7,6 @@ ldflags-y += --wrap=nvdimm_bus_register
 ldflags-y += --wrap=cxl_await_media_ready
 ldflags-y += --wrap=devm_cxl_add_rch_dport
 ldflags-y += --wrap=cxl_endpoint_parse_cdat
-ldflags-y += --wrap=cxl_dport_init_ras_reporting
 ldflags-y += --wrap=devm_cxl_endpoint_decoders_setup
 ldflags-y += --wrap=hmat_get_extended_linear_cache_size
 ldflags-y += --wrap=devm_cxl_add_dport_by_dev
index f307c5b391847924e4d2847d11d44aae30346900..b8fcb50c10278ad8133bf01bb1feba023e5617cd 100644 (file)
@@ -234,18 +234,6 @@ void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port)
 }
 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, "CXL");
 
-void __wrap_cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
-{
-       int index;
-       struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
-
-       if (!ops || !ops->is_mock_port(dport->dport_dev))
-               cxl_dport_init_ras_reporting(dport, host);
-
-       put_cxl_mock_ops(index);
-}
-EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dport_init_ras_reporting, "CXL");
-
 struct cxl_dport *__wrap_devm_cxl_add_dport_by_dev(struct cxl_port *port,
                                                   struct device *dport_dev)
 {