RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / edac / edac_module.c
blob73cc9923f38786b26cf17aa4f1ccdf212962b16b
1 /*
2 * edac_module.c
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);
24 #endif
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 = {
34 .name = "edac",
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)
44 return "POLLED";
45 else if (opstate == OP_RUNNING_INTERRUPT)
46 return "INTERRUPT";
47 else if (opstate == OP_RUNNING_POLL_INTR)
48 return "POLL-INTR";
49 else if (opstate == OP_ALLOC)
50 return "ALLOC";
51 else if (opstate == OP_OFFLINE)
52 return "OFFLINE";
54 return "UNKNOWN";
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;
66 if (edac_class_valid)
67 classptr = &edac_class;
69 return classptr;
73 * edac_register_sysfs_edac_name()
75 * register the 'edac' into /sys/devices/system
77 * return:
78 * 0 success
79 * !0 error
81 static int edac_register_sysfs_edac_name(void)
83 int err;
85 /* create the /sys/devices/system/edac directory */
86 err = sysdev_class_register(&edac_class);
88 if (err) {
89 debugf1("%s() error=%d\n", __func__, err);
90 return err;
93 edac_class_valid = 1;
94 return 0;
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)
119 return -ENODEV;
120 else
121 return 0;
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;
138 * edac_init
139 * module initialization entry point
141 static int __init edac_init(void)
143 int err = 0;
145 edac_printk(KERN_INFO, EDAC_MC, EDAC_VERSION "\n");
147 edac_pci_clear_parity_errors();
150 * perform the registration of the /sys/devices/system/edac class object
152 if (edac_register_sysfs_edac_name()) {
153 edac_printk(KERN_ERR, EDAC_MC,
154 "Error initializing 'edac' kobject\n");
155 err = -ENODEV;
156 goto error;
160 * now set up the mc_kset under the edac class object
162 err = edac_sysfs_setup_mc_kset();
163 if (err)
164 goto sysfs_setup_fail;
166 /* Setup/Initialize the workq for this core */
167 err = edac_workqueue_setup();
168 if (err) {
169 edac_printk(KERN_ERR, EDAC_MC, "init WorkQueue failure\n");
170 goto workq_fail;
173 return 0;
175 /* Error teardown stack */
176 workq_fail:
177 edac_sysfs_teardown_mc_kset();
179 sysfs_setup_fail:
180 edac_unregister_sysfs_edac_name();
182 error:
183 return err;
187 * edac_exit()
188 * module exit/termination function
190 static void __exit edac_exit(void)
192 debugf0("%s()\n", __func__);
194 /* tear down the various subsystems */
195 edac_workqueue_teardown();
196 edac_sysfs_teardown_mc_kset();
197 edac_unregister_sysfs_edac_name();
201 * Inform the kernel of our entry and exit points
203 module_init(edac_init);
204 module_exit(edac_exit);
206 MODULE_LICENSE("GPL");
207 MODULE_AUTHOR("Doug Thompson www.softwarebitmaker.com, et al");
208 MODULE_DESCRIPTION("Core library routines for EDAC reporting");
210 /* refer to *_sysfs.c files for parameters that are exported via sysfs */
212 #ifdef CONFIG_EDAC_DEBUG
213 module_param(edac_debug_level, int, 0644);
214 MODULE_PARM_DESC(edac_debug_level, "Debug level");
215 #endif