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");