]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cxl: Move pci generic code from cxl_pci to core/cxl_pci
authorAlejandro Lucero <alucerop@amd.com>
Fri, 6 Mar 2026 16:47:40 +0000 (16:47 +0000)
committerDave Jiang <dave.jiang@intel.com>
Mon, 16 Mar 2026 23:30:22 +0000 (16:30 -0700)
Inside cxl/core/pci.c there are helpers for CXL PCIe initialization
meanwhile cxl/pci_drv.c implements the functionality for a Type3 device
initialization.

In preparation for type2 support, move helper functions from cxl/pci.c to
cxl/core/pci.c in order to be exported and used by type2 drivers.

[ dj: Clarified subject. ]

Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Gregory Price <gourry@gourry.net>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: Gregory Price <gourry@gourry.net>
Link: https://patch.msgid.link/20260306164741.3796372-4-alejandro.lucero-palau@amd.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/core/core.h
drivers/cxl/core/pci.c
drivers/cxl/core/regs.c
drivers/cxl/cxl.h
drivers/cxl/cxlpci.h
drivers/cxl/pci.c

index 5b0570df0fd9c9629d68956aa7a3dabe45639a37..5539e941782f6284a0a4a3977e9206bc2a68844b 100644 (file)
@@ -224,4 +224,6 @@ int cxl_set_feature(struct cxl_mailbox *cxl_mbox, const uuid_t *feat_uuid,
                    u16 *return_code);
 #endif
 
+resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
+                                          struct cxl_dport *dport);
 #endif /* __CXL_CORE_H__ */
index f96ce884a213061c6ecc7189d867cee5edc51cd5..c32cc62c501de3a422b126516c42dea6f53273f5 100644 (file)
@@ -696,6 +696,68 @@ bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port)
 }
 EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, "CXL");
 
+static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
+                                 struct cxl_register_map *map,
+                                 struct cxl_dport *dport)
+{
+       resource_size_t component_reg_phys;
+
+       *map = (struct cxl_register_map) {
+               .host = &pdev->dev,
+               .resource = CXL_RESOURCE_NONE,
+       };
+
+       struct cxl_port *port __free(put_cxl_port) =
+               cxl_pci_find_port(pdev, &dport);
+       if (!port)
+               return -EPROBE_DEFER;
+
+       component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
+       if (component_reg_phys == CXL_RESOURCE_NONE)
+               return -ENXIO;
+
+       map->resource = component_reg_phys;
+       map->reg_type = CXL_REGLOC_RBI_COMPONENT;
+       map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
+
+       return 0;
+}
+
+int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
+                      struct cxl_register_map *map)
+{
+       int rc;
+
+       rc = cxl_find_regblock(pdev, type, map);
+
+       /*
+        * If the Register Locator DVSEC does not exist, check if it
+        * is an RCH and try to extract the Component Registers from
+        * an RCRB.
+        */
+       if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev)) {
+               struct cxl_dport *dport;
+               struct cxl_port *port __free(put_cxl_port) =
+                       cxl_pci_find_port(pdev, &dport);
+               if (!port)
+                       return -EPROBE_DEFER;
+
+               rc = cxl_rcrb_get_comp_regs(pdev, map, dport);
+               if (rc)
+                       return rc;
+
+               rc = cxl_dport_map_rcd_linkcap(pdev, dport);
+               if (rc)
+                       return rc;
+
+       } else if (rc) {
+               return rc;
+       }
+
+       return cxl_setup_regs(map);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_pci_setup_regs, "CXL");
+
 int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
 {
        int speed, bw;
index a010b321434229ece55a7053c764079bd7612faa..93710cf4f0a6971f2176c9acdad03c8516ec6a89 100644 (file)
@@ -641,4 +641,3 @@ resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
                return CXL_RESOURCE_NONE;
        return __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM);
 }
-EXPORT_SYMBOL_NS_GPL(cxl_rcd_component_reg_phys, "CXL");
index 1d94217729f7669ff8ca0506f0009e44b8dc9045..8194447f75d30fe32caad06d62cc52351faea93e 100644 (file)
@@ -222,8 +222,6 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
                      struct cxl_register_map *map);
 int cxl_setup_regs(struct cxl_register_map *map);
 struct cxl_dport;
-resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
-                                          struct cxl_dport *dport);
 int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport);
 
 #define CXL_RESOURCE_NONE ((resource_size_t) -1)
index 0cf64218aa16ec8ff4b85a07a89727b694c4de90..b826eb53cf7bacdbe79c70a6574a45340369bad2 100644 (file)
@@ -74,6 +74,17 @@ static inline bool cxl_pci_flit_256(struct pci_dev *pdev)
        return lnksta2 & PCI_EXP_LNKSTA2_FLIT;
 }
 
+/*
+ * Assume that the caller has already validated that @pdev has CXL
+ * capabilities, any RCiEP with CXL capabilities is treated as a
+ * Restricted CXL Device (RCD) and finds upstream port and endpoint
+ * registers in a Root Complex Register Block (RCRB).
+ */
+static inline bool is_cxl_restricted(struct pci_dev *pdev)
+{
+       return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
+}
+
 struct cxl_dev_state;
 void read_cdat_data(struct cxl_port *port);
 
@@ -101,4 +112,6 @@ static inline void devm_cxl_port_ras_setup(struct cxl_port *port)
 }
 #endif
 
+int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
+                      struct cxl_register_map *map);
 #endif /* __CXL_PCI_H__ */
index a42f273ff72b41544ca2f453ee8fada3d188bb44..adc7c4bcb03aa52254922224b1e399167ac4e0b9 100644 (file)
@@ -465,76 +465,6 @@ static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds, bool irq_avail)
        return 0;
 }
 
-/*
- * Assume that any RCIEP that emits the CXL memory expander class code
- * is an RCD
- */
-static bool is_cxl_restricted(struct pci_dev *pdev)
-{
-       return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
-}
-
-static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
-                                 struct cxl_register_map *map,
-                                 struct cxl_dport *dport)
-{
-       resource_size_t component_reg_phys;
-
-       *map = (struct cxl_register_map) {
-               .host = &pdev->dev,
-               .resource = CXL_RESOURCE_NONE,
-       };
-
-       struct cxl_port *port __free(put_cxl_port) =
-               cxl_pci_find_port(pdev, &dport);
-       if (!port)
-               return -EPROBE_DEFER;
-
-       component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
-       if (component_reg_phys == CXL_RESOURCE_NONE)
-               return -ENXIO;
-
-       map->resource = component_reg_phys;
-       map->reg_type = CXL_REGLOC_RBI_COMPONENT;
-       map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
-
-       return 0;
-}
-
-static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
-                             struct cxl_register_map *map)
-{
-       int rc;
-
-       rc = cxl_find_regblock(pdev, type, map);
-
-       /*
-        * If the Register Locator DVSEC does not exist, check if it
-        * is an RCH and try to extract the Component Registers from
-        * an RCRB.
-        */
-       if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev)) {
-               struct cxl_dport *dport;
-               struct cxl_port *port __free(put_cxl_port) =
-                       cxl_pci_find_port(pdev, &dport);
-               if (!port)
-                       return -EPROBE_DEFER;
-
-               rc = cxl_rcrb_get_comp_regs(pdev, map, dport);
-               if (rc)
-                       return rc;
-
-               rc = cxl_dport_map_rcd_linkcap(pdev, dport);
-               if (rc)
-                       return rc;
-
-       } else if (rc) {
-               return rc;
-       }
-
-       return cxl_setup_regs(map);
-}
-
 static void free_event_buf(void *buf)
 {
        kvfree(buf);