struct cxl_decoder *cxld;
 
                if (is_cxl_endpoint(port)) {
-                       cxld = cxl_endpoint_decoder_alloc(port);
-                       if (IS_ERR(cxld)) {
+                       struct cxl_endpoint_decoder *cxled;
+
+                       cxled = cxl_endpoint_decoder_alloc(port);
+                       if (IS_ERR(cxled)) {
                                dev_warn(&port->dev,
                                         "Failed to allocate the decoder\n");
-                               return PTR_ERR(cxld);
+                               return PTR_ERR(cxled);
                        }
+                       cxld = &cxled->cxld;
                } else {
                        struct cxl_switch_decoder *cxlsd;
 
 
        put_device(&port->dev);
 }
 
-static void cxl_decoder_release(struct device *dev)
+static void cxl_endpoint_decoder_release(struct device *dev)
 {
-       struct cxl_decoder *cxld = to_cxl_decoder(dev);
+       struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
 
-       __cxl_decoder_release(cxld);
-       kfree(cxld);
+       __cxl_decoder_release(&cxled->cxld);
+       kfree(cxled);
 }
 
 static void cxl_switch_decoder_release(struct device *dev)
 
 static const struct device_type cxl_decoder_endpoint_type = {
        .name = "cxl_decoder_endpoint",
-       .release = cxl_decoder_release,
+       .release = cxl_endpoint_decoder_release,
        .groups = cxl_decoder_endpoint_attribute_groups,
 };
 
 }
 EXPORT_SYMBOL_NS_GPL(to_cxl_decoder, CXL);
 
+struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev)
+{
+       if (dev_WARN_ONCE(dev, !is_endpoint_decoder(dev),
+                         "not a cxl_endpoint_decoder device\n"))
+               return NULL;
+       return container_of(dev, struct cxl_endpoint_decoder, cxld.dev);
+}
+EXPORT_SYMBOL_NS_GPL(to_cxl_endpoint_decoder, CXL);
+
 static struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev)
 {
        if (dev_WARN_ONCE(dev, !is_switch_decoder(dev),
  *
  * Return: A new cxl decoder to be registered by cxl_decoder_add()
  */
-struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
+struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
 {
+       struct cxl_endpoint_decoder *cxled;
        struct cxl_decoder *cxld;
        int rc;
 
        if (!is_cxl_endpoint(port))
                return ERR_PTR(-EINVAL);
 
-       cxld = kzalloc(sizeof(*cxld), GFP_KERNEL);
-       if (!cxld)
+       cxled = kzalloc(sizeof(*cxled), GFP_KERNEL);
+       if (!cxled)
                return ERR_PTR(-ENOMEM);
 
+       cxld = &cxled->cxld;
        rc = cxl_decoder_init(port, cxld);
        if (rc)  {
-               kfree(cxld);
+               kfree(cxled);
                return ERR_PTR(rc);
        }
 
        cxld->dev.type = &cxl_decoder_endpoint_type;
-       return cxld;
+       return cxled;
 }
 EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_alloc, CXL);
 
 
        unsigned long flags;
 };
 
+/**
+ * struct cxl_endpoint_decoder - Endpoint  / SPA to DPA decoder
+ * @cxld: base cxl_decoder_object
+ * @dpa_res: actively claimed DPA span of this decoder
+ * @skip: offset into @dpa_res where @cxld.hpa_range maps
+ */
+struct cxl_endpoint_decoder {
+       struct cxl_decoder cxld;
+       struct resource *dpa_res;
+       resource_size_t skip;
+};
+
 /**
  * struct cxl_switch_decoder - Switch specific CXL HDM Decoder
  * @cxld: base cxl_decoder object
 
 struct cxl_decoder *to_cxl_decoder(struct device *dev);
 struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev);
+struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev);
 bool is_root_decoder(struct device *dev);
 bool is_endpoint_decoder(struct device *dev);
 struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
 struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port,
                                                    unsigned int nr_targets);
 int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);
-struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
+struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
 int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map);
 int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld);
 int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint);