// SPDX-License-Identifier: GPL-2.0-only
 /* Copyright(c) 2022 Intel Corporation. All rights reserved. */
 #include <linux/io-64-nonatomic-hi-lo.h>
+#include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/delay.h>
 
  * for enumerating these registers and capabilities.
  */
 
+static DECLARE_RWSEM(cxl_dpa_rwsem);
+
 static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
                           int *target_map)
 {
 }
 EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_hdm, CXL);
 
+static void __cxl_dpa_debug(struct seq_file *file, struct resource *r, int depth)
+{
+       unsigned long long start = r->start, end = r->end;
+
+       seq_printf(file, "%*s%08llx-%08llx : %s\n", depth * 2, "", start, end,
+                  r->name);
+}
+
+void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds)
+{
+       struct resource *p1, *p2;
+
+       down_read(&cxl_dpa_rwsem);
+       for (p1 = cxlds->dpa_res.child; p1; p1 = p1->sibling) {
+               __cxl_dpa_debug(file, p1, 0);
+               for (p2 = p1->child; p2; p2 = p2->sibling)
+                       __cxl_dpa_debug(file, p2, 1);
+       }
+       up_read(&cxl_dpa_rwsem);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_dpa_debug, CXL);
+
 static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
                            int *target_map, void __iomem *hdm, int which)
 {
 
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright(c) 2022 Intel Corporation. All rights reserved. */
+#include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
        cxl_mem_active_dec();
 }
 
+static void remove_debugfs(void *dentry)
+{
+       debugfs_remove_recursive(dentry);
+}
+
+static int cxl_mem_dpa_show(struct seq_file *file, void *data)
+{
+       struct device *dev = file->private;
+       struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
+
+       cxl_dpa_debug(file, cxlmd->cxlds);
+
+       return 0;
+}
+
 static int cxl_mem_probe(struct device *dev)
 {
        struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
        struct cxl_port *parent_port;
+       struct dentry *dentry;
        int rc;
 
        /*
        if (work_pending(&cxlmd->detach_work))
                return -EBUSY;
 
+       dentry = cxl_debugfs_create_dir(dev_name(dev));
+       debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
+       rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
+       if (rc)
+               return rc;
+
        rc = devm_cxl_enumerate_ports(cxlmd);
        if (rc)
                return rc;