4 * (C) 2007 www.softwarebitmaker.com
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
10 * Author: Doug Thompson <dougthompson@xmission.com>
13 #include <linux/edac.h>
15 #include "edac_core.h"
16 #include "edac_module.h"
18 #define EDAC_VERSION "Ver: 2.1.0 " __DATE__
20 #ifdef CONFIG_EDAC_DEBUG
21 /* Values of 0 to 4 will generate output */
22 int edac_debug_level
= 2;
23 EXPORT_SYMBOL_GPL(edac_debug_level
);
26 /* scope is to module level only */
27 struct workqueue_struct
*edac_workqueue
;
30 * sysfs object: /sys/devices/system/edac
31 * need to export to other files in this modules
33 static struct sysdev_class edac_class
= {
36 static int edac_class_valid
;
39 * edac_op_state_to_string()
41 char *edac_op_state_to_string(int opstate
)
43 if (opstate
== OP_RUNNING_POLL
)
45 else if (opstate
== OP_RUNNING_INTERRUPT
)
47 else if (opstate
== OP_RUNNING_POLL_INTR
)
49 else if (opstate
== OP_ALLOC
)
51 else if (opstate
== OP_OFFLINE
)
58 * edac_get_edac_class()
60 * return pointer to the edac class of 'edac'
62 struct sysdev_class
*edac_get_edac_class(void)
64 struct sysdev_class
*classptr
= NULL
;
67 classptr
= &edac_class
;
73 * edac_register_sysfs_edac_name()
75 * register the 'edac' into /sys/devices/system
81 static int edac_register_sysfs_edac_name(void)
85 /* create the /sys/devices/system/edac directory */
86 err
= sysdev_class_register(&edac_class
);
89 debugf1("%s() error=%d\n", __func__
, err
);
98 * sysdev_class_unregister()
100 * unregister the 'edac' from /sys/devices/system
102 static void edac_unregister_sysfs_edac_name(void)
104 /* only if currently registered, then unregister it */
105 if (edac_class_valid
)
106 sysdev_class_unregister(&edac_class
);
108 edac_class_valid
= 0;
112 * edac_workqueue_setup
113 * initialize the edac work queue for polling operations
115 static int edac_workqueue_setup(void)
117 edac_workqueue
= create_singlethread_workqueue("edac-poller");
118 if (edac_workqueue
== NULL
)
125 * edac_workqueue_teardown
126 * teardown the edac workqueue
128 static void edac_workqueue_teardown(void)
130 if (edac_workqueue
) {
131 flush_workqueue(edac_workqueue
);
132 destroy_workqueue(edac_workqueue
);
133 edac_workqueue
= NULL
;
139 * module initialization entry point
141 static int __init
edac_init(void)
145 edac_printk(KERN_INFO
, EDAC_MC
, EDAC_VERSION
"\n");
148 * Harvest and clear any boot/initialization PCI parity errors
150 * FIXME: This only clears errors logged by devices present at time of
151 * module initialization. We should also do an initial clear
152 * of each newly hotplugged device.
154 edac_pci_clear_parity_errors();
157 * perform the registration of the /sys/devices/system/edac class object
159 if (edac_register_sysfs_edac_name()) {
160 edac_printk(KERN_ERR
, EDAC_MC
,
161 "Error initializing 'edac' kobject\n");
167 * now set up the mc_kset under the edac class object
169 err
= edac_sysfs_setup_mc_kset();
171 goto sysfs_setup_fail
;
173 /* Setup/Initialize the workq for this core */
174 err
= edac_workqueue_setup();
176 edac_printk(KERN_ERR
, EDAC_MC
, "init WorkQueue failure\n");
182 /* Error teardown stack */
184 edac_sysfs_teardown_mc_kset();
187 edac_unregister_sysfs_edac_name();
195 * module exit/termination function
197 static void __exit
edac_exit(void)
199 debugf0("%s()\n", __func__
);
201 /* tear down the various subsystems */
202 edac_workqueue_teardown();
203 edac_sysfs_teardown_mc_kset();
204 edac_unregister_sysfs_edac_name();
208 * Inform the kernel of our entry and exit points
210 module_init(edac_init
);
211 module_exit(edac_exit
);
213 MODULE_LICENSE("GPL");
214 MODULE_AUTHOR("Doug Thompson www.softwarebitmaker.com, et al");
215 MODULE_DESCRIPTION("Core library routines for EDAC reporting");
217 /* refer to *_sysfs.c files for parameters that are exported via sysfs */
219 #ifdef CONFIG_EDAC_DEBUG
220 module_param(edac_debug_level
, int, 0644);
221 MODULE_PARM_DESC(edac_debug_level
, "Debug level");