0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/edac.h>
0014
0015 #include "edac_mc.h"
0016 #include "edac_module.h"
0017
0018 #define EDAC_VERSION "Ver: 3.0.0"
0019
0020 #ifdef CONFIG_EDAC_DEBUG
0021
0022 static int edac_set_debug_level(const char *buf,
0023 const struct kernel_param *kp)
0024 {
0025 unsigned long val;
0026 int ret;
0027
0028 ret = kstrtoul(buf, 0, &val);
0029 if (ret)
0030 return ret;
0031
0032 if (val > 4)
0033 return -EINVAL;
0034
0035 return param_set_int(buf, kp);
0036 }
0037
0038
0039 int edac_debug_level = 2;
0040 EXPORT_SYMBOL_GPL(edac_debug_level);
0041
0042 module_param_call(edac_debug_level, edac_set_debug_level, param_get_int,
0043 &edac_debug_level, 0644);
0044 MODULE_PARM_DESC(edac_debug_level, "EDAC debug level: [0-4], default: 2");
0045 #endif
0046
0047
0048
0049
0050 char *edac_op_state_to_string(int opstate)
0051 {
0052 if (opstate == OP_RUNNING_POLL)
0053 return "POLLED";
0054 else if (opstate == OP_RUNNING_INTERRUPT)
0055 return "INTERRUPT";
0056 else if (opstate == OP_RUNNING_POLL_INTR)
0057 return "POLL-INTR";
0058 else if (opstate == OP_ALLOC)
0059 return "ALLOC";
0060 else if (opstate == OP_OFFLINE)
0061 return "OFFLINE";
0062
0063 return "UNKNOWN";
0064 }
0065
0066
0067
0068
0069
0070 static struct bus_type edac_subsys = {
0071 .name = "edac",
0072 .dev_name = "edac",
0073 };
0074
0075 static int edac_subsys_init(void)
0076 {
0077 int err;
0078
0079
0080 err = subsys_system_register(&edac_subsys, NULL);
0081 if (err)
0082 printk(KERN_ERR "Error registering toplevel EDAC sysfs dir\n");
0083
0084 return err;
0085 }
0086
0087 static void edac_subsys_exit(void)
0088 {
0089 bus_unregister(&edac_subsys);
0090 }
0091
0092
0093 struct bus_type *edac_get_sysfs_subsys(void)
0094 {
0095 return &edac_subsys;
0096 }
0097 EXPORT_SYMBOL_GPL(edac_get_sysfs_subsys);
0098
0099
0100
0101
0102 static int __init edac_init(void)
0103 {
0104 int err = 0;
0105
0106 edac_printk(KERN_INFO, EDAC_MC, EDAC_VERSION "\n");
0107
0108 err = edac_subsys_init();
0109 if (err)
0110 return err;
0111
0112
0113
0114
0115
0116
0117
0118
0119 edac_pci_clear_parity_errors();
0120
0121 err = edac_mc_sysfs_init();
0122 if (err)
0123 goto err_sysfs;
0124
0125 edac_debugfs_init();
0126
0127 err = edac_workqueue_setup();
0128 if (err) {
0129 edac_printk(KERN_ERR, EDAC_MC, "Failure initializing workqueue\n");
0130 goto err_wq;
0131 }
0132
0133 return 0;
0134
0135 err_wq:
0136 edac_debugfs_exit();
0137 edac_mc_sysfs_exit();
0138
0139 err_sysfs:
0140 edac_subsys_exit();
0141
0142 return err;
0143 }
0144
0145
0146
0147
0148
0149 static void __exit edac_exit(void)
0150 {
0151 edac_dbg(0, "\n");
0152
0153
0154 edac_workqueue_teardown();
0155 edac_mc_sysfs_exit();
0156 edac_debugfs_exit();
0157 edac_subsys_exit();
0158 }
0159
0160
0161
0162
0163 subsys_initcall(edac_init);
0164 module_exit(edac_exit);
0165
0166 MODULE_LICENSE("GPL");
0167 MODULE_AUTHOR("Doug Thompson www.softwarebitmaker.com, et al");
0168 MODULE_DESCRIPTION("Core library routines for EDAC reporting");