0001
0002
0003 #include <linux/debugfs.h>
0004 #include <linux/device.h>
0005 #include <linux/module.h>
0006 #include <linux/pci.h>
0007
0008 #include "cxlmem.h"
0009 #include "cxlpci.h"
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 static void enable_suspend(void *data)
0029 {
0030 cxl_mem_active_dec();
0031 }
0032
0033 static void remove_debugfs(void *dentry)
0034 {
0035 debugfs_remove_recursive(dentry);
0036 }
0037
0038 static int cxl_mem_dpa_show(struct seq_file *file, void *data)
0039 {
0040 struct device *dev = file->private;
0041 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
0042
0043 cxl_dpa_debug(file, cxlmd->cxlds);
0044
0045 return 0;
0046 }
0047
0048 static int cxl_mem_probe(struct device *dev)
0049 {
0050 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
0051 struct cxl_port *parent_port;
0052 struct cxl_dport *dport;
0053 struct dentry *dentry;
0054 int rc;
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 if (work_pending(&cxlmd->detach_work))
0065 return -EBUSY;
0066
0067 dentry = cxl_debugfs_create_dir(dev_name(dev));
0068 debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
0069 rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
0070 if (rc)
0071 return rc;
0072
0073 rc = devm_cxl_enumerate_ports(cxlmd);
0074 if (rc)
0075 return rc;
0076
0077 parent_port = cxl_mem_find_port(cxlmd, &dport);
0078 if (!parent_port) {
0079 dev_err(dev, "CXL port topology not found\n");
0080 return -ENXIO;
0081 }
0082
0083 device_lock(&parent_port->dev);
0084 if (!parent_port->dev.driver) {
0085 dev_err(dev, "CXL port topology %s not enabled\n",
0086 dev_name(&parent_port->dev));
0087 rc = -ENXIO;
0088 goto unlock;
0089 }
0090
0091 rc = devm_cxl_add_endpoint(cxlmd, dport);
0092 unlock:
0093 device_unlock(&parent_port->dev);
0094 put_device(&parent_port->dev);
0095 if (rc)
0096 return rc;
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 cxl_mem_active_inc();
0112 return devm_add_action_or_reset(dev, enable_suspend, NULL);
0113 }
0114
0115 static struct cxl_driver cxl_mem_driver = {
0116 .name = "cxl_mem",
0117 .probe = cxl_mem_probe,
0118 .id = CXL_DEVICE_MEMORY_EXPANDER,
0119 };
0120
0121 module_cxl_driver(cxl_mem_driver);
0122
0123 MODULE_LICENSE("GPL v2");
0124 MODULE_IMPORT_NS(CXL);
0125 MODULE_ALIAS_CXL(CXL_DEVICE_MEMORY_EXPANDER);
0126
0127
0128
0129
0130 MODULE_SOFTDEP("pre: cxl_port");