]> git.itanic.dy.fi Git - linux-stable/blobdiff - drivers/cxl/core/hdm.c
Merge branch 'for-6.7/cxl-commited' into cxl/next
[linux-stable] / drivers / cxl / core / hdm.c
index 7d112557c9399007a6c9331e98eb42f268834a91..bc8ad4a8afca2349c75f67d4d235b4d5827a20a0 100644 (file)
@@ -81,26 +81,6 @@ static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm)
                cxlhdm->interleave_mask |= GENMASK(14, 12);
 }
 
-static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb,
-                               struct cxl_component_regs *regs)
-{
-       struct cxl_register_map map = {
-               .dev = &port->dev,
-               .resource = port->component_reg_phys,
-               .base = crb,
-               .max_size = CXL_COMPONENT_REG_BLOCK_SIZE,
-       };
-
-       cxl_probe_component_regs(&port->dev, crb, &map.component_map);
-       if (!map.component_map.hdm_decoder.valid) {
-               dev_dbg(&port->dev, "HDM decoder registers not implemented\n");
-               /* unique error code to indicate no HDM decoder capability */
-               return -ENODEV;
-       }
-
-       return cxl_map_component_regs(&map, regs, BIT(CXL_CM_CAP_CAP_ID_HDM));
-}
-
 static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
 {
        struct cxl_hdm *cxlhdm;
@@ -153,9 +133,9 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
 struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
                                   struct cxl_endpoint_dvsec_info *info)
 {
+       struct cxl_register_map *reg_map = &port->reg_map;
        struct device *dev = &port->dev;
        struct cxl_hdm *cxlhdm;
-       void __iomem *crb;
        int rc;
 
        cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL);
@@ -164,19 +144,29 @@ struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
        cxlhdm->port = port;
        dev_set_drvdata(dev, cxlhdm);
 
-       crb = ioremap(port->component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE);
-       if (!crb && info && info->mem_enabled) {
+       /* Memory devices can configure device HDM using DVSEC range regs. */
+       if (reg_map->resource == CXL_RESOURCE_NONE) {
+               if (!info && !info->mem_enabled) {
+                       dev_err(dev, "No component registers mapped\n");
+                       return ERR_PTR(-ENXIO);
+               }
+
                cxlhdm->decoder_count = info->ranges;
                return cxlhdm;
-       } else if (!crb) {
-               dev_err(dev, "No component registers mapped\n");
-               return ERR_PTR(-ENXIO);
        }
 
-       rc = map_hdm_decoder_regs(port, crb, &cxlhdm->regs);
-       iounmap(crb);
-       if (rc)
+       if (!reg_map->component_map.hdm_decoder.valid) {
+               dev_dbg(&port->dev, "HDM decoder registers not implemented\n");
+               /* unique error code to indicate no HDM decoder capability */
+               return ERR_PTR(-ENODEV);
+       }
+
+       rc = cxl_map_component_regs(reg_map, &cxlhdm->regs,
+                                   BIT(CXL_CM_CAP_CAP_ID_HDM));
+       if (rc) {
+               dev_err(dev, "Failed to map HDM capability.\n");
                return ERR_PTR(rc);
+       }
 
        parse_hdm_decoder_caps(cxlhdm);
        if (cxlhdm->decoder_count == 0) {