return 0;
 }
 
-static bool should_emulate_decoders(struct cxl_port *port)
+static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
 {
-       struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
-       void __iomem *hdm = cxlhdm->regs.hdm_decoder;
+       struct cxl_hdm *cxlhdm;
+       void __iomem *hdm;
        u32 ctrl;
        int i;
 
-       if (!is_cxl_endpoint(cxlhdm->port))
+       if (!info)
                return false;
 
+       cxlhdm = dev_get_drvdata(&info->port->dev);
+       hdm = cxlhdm->regs.hdm_decoder;
+
        if (!hdm)
                return true;
 
+       /*
+        * If HDM decoders are present and the driver is in control of
+        * Mem_Enable skip DVSEC based emulation
+        */
+       if (!info->mem_enabled)
+               return false;
+
        /*
         * If any decoders are committed already, there should not be any
         * emulated DVSEC decoders.
                            int *target_map, void __iomem *hdm, int which,
                            u64 *dpa_base, struct cxl_endpoint_dvsec_info *info)
 {
-       struct cxl_endpoint_decoder *cxled = NULL;
+       struct cxl_endpoint_decoder *cxled;
        u64 size, base, skip, dpa_size;
        bool committed;
        u32 remainder;
                unsigned char target_id[8];
        } target_list;
 
-       if (should_emulate_decoders(port))
+       if (should_emulate_decoders(info))
                return cxl_setup_hdm_decoder_from_dvsec(port, cxld, which, info);
 
-       if (is_endpoint_decoder(&cxld->dev))
-               cxled = to_cxl_endpoint_decoder(&cxld->dev);
-
        ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which));
        base = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(which));
        size = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(which));
                .end = base + size - 1,
        };
 
-       if (cxled && !committed && range_len(&info->dvsec_range[which]))
-               return cxl_setup_hdm_decoder_from_dvsec(port, cxld, which, info);
-
        /* decoders are enabled if committed */
        if (committed) {
                cxld->flags |= CXL_DECODER_F_ENABLE;
        if (rc)
                return rc;
 
-       if (!cxled) {
+       if (!info) {
                target_list.value =
                        ioread64_hi_lo(hdm + CXL_HDM_DECODER0_TL_LOW(which));
                for (i = 0; i < cxld->interleave_ways; i++)
                return -ENXIO;
        }
        skip = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_SKIP_LOW(which));
+       cxled = to_cxl_endpoint_decoder(&cxld->dev);
        rc = devm_cxl_dpa_reserve(cxled, *dpa_base + skip, dpa_size, skip);
        if (rc) {
                dev_err(&port->dev,
 
 
 /**
  * struct cxl_endpoint_dvsec_info - Cached DVSEC info
- * @mem_enabled: cached value of mem_enabled in the DVSEC, PCIE_DEVICE
+ * @mem_enabled: cached value of mem_enabled in the DVSEC at init time
  * @ranges: Number of active HDM ranges this device uses.
+ * @port: endpoint port associated with this info instance
  * @dvsec_range: cached attributes of the ranges in the DVSEC, PCIE_DEVICE
  */
 struct cxl_endpoint_dvsec_info {
        bool mem_enabled;
        int ranges;
+       struct cxl_port *port;
        struct range dvsec_range[2];
 };