linux/drivers/edac/edac_module.c
<<
>>
Prefs
   1/*
   2 * edac_module.c
   3 *
   4 * (C) 2007 www.softwarebitmaker.com
   5 *
   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.
   9 *
  10 * Author: Doug Thompson <dougthompson@xmission.com>
  11 *
  12 */
  13#include <linux/edac.h>
  14
  15#include "edac_core.h"
  16#include "edac_module.h"
  17
  18#define EDAC_VERSION "Ver: 2.1.0"
  19
  20#ifdef CONFIG_EDAC_DEBUG
  21/* Values of 0 to 4 will generate output */
  22int edac_debug_level = 2;
  23EXPORT_SYMBOL_GPL(edac_debug_level);
  24#endif
  25
  26/* scope is to module level only */
  27struct workqueue_struct *edac_workqueue;
  28
  29/*
  30 * edac_op_state_to_string()
  31 */
  32char *edac_op_state_to_string(int opstate)
  33{
  34        if (opstate == OP_RUNNING_POLL)
  35                return "POLLED";
  36        else if (opstate == OP_RUNNING_INTERRUPT)
  37                return "INTERRUPT";
  38        else if (opstate == OP_RUNNING_POLL_INTR)
  39                return "POLL-INTR";
  40        else if (opstate == OP_ALLOC)
  41                return "ALLOC";
  42        else if (opstate == OP_OFFLINE)
  43                return "OFFLINE";
  44
  45        return "UNKNOWN";
  46}
  47
  48/*
  49 * edac_workqueue_setup
  50 *      initialize the edac work queue for polling operations
  51 */
  52static int edac_workqueue_setup(void)
  53{
  54        edac_workqueue = create_singlethread_workqueue("edac-poller");
  55        if (edac_workqueue == NULL)
  56                return -ENODEV;
  57        else
  58                return 0;
  59}
  60
  61/*
  62 * edac_workqueue_teardown
  63 *      teardown the edac workqueue
  64 */
  65static void edac_workqueue_teardown(void)
  66{
  67        if (edac_workqueue) {
  68                flush_workqueue(edac_workqueue);
  69                destroy_workqueue(edac_workqueue);
  70                edac_workqueue = NULL;
  71        }
  72}
  73
  74/*
  75 * edac_init
  76 *      module initialization entry point
  77 */
  78static int __init edac_init(void)
  79{
  80        int err = 0;
  81
  82        edac_printk(KERN_INFO, EDAC_MC, EDAC_VERSION "\n");
  83
  84        /*
  85         * Harvest and clear any boot/initialization PCI parity errors
  86         *
  87         * FIXME: This only clears errors logged by devices present at time of
  88         *      module initialization.  We should also do an initial clear
  89         *      of each newly hotplugged device.
  90         */
  91        edac_pci_clear_parity_errors();
  92
  93        /*
  94         * now set up the mc_kset under the edac class object
  95         */
  96        err = edac_sysfs_setup_mc_kset();
  97        if (err)
  98                goto error;
  99
 100        /* Setup/Initialize the workq for this core */
 101        err = edac_workqueue_setup();
 102        if (err) {
 103                edac_printk(KERN_ERR, EDAC_MC, "init WorkQueue failure\n");
 104                goto workq_fail;
 105        }
 106
 107        return 0;
 108
 109        /* Error teardown stack */
 110workq_fail:
 111        edac_sysfs_teardown_mc_kset();
 112
 113error:
 114        return err;
 115}
 116
 117/*
 118 * edac_exit()
 119 *      module exit/termination function
 120 */
 121static void __exit edac_exit(void)
 122{
 123        debugf0("%s()\n", __func__);
 124
 125        /* tear down the various subsystems */
 126        edac_workqueue_teardown();
 127        edac_sysfs_teardown_mc_kset();
 128}
 129
 130/*
 131 * Inform the kernel of our entry and exit points
 132 */
 133module_init(edac_init);
 134module_exit(edac_exit);
 135
 136MODULE_LICENSE("GPL");
 137MODULE_AUTHOR("Doug Thompson www.softwarebitmaker.com, et al");
 138MODULE_DESCRIPTION("Core library routines for EDAC reporting");
 139
 140/* refer to *_sysfs.c files for parameters that are exported via sysfs */
 141
 142#ifdef CONFIG_EDAC_DEBUG
 143module_param(edac_debug_level, int, 0644);
 144MODULE_PARM_DESC(edac_debug_level, "Debug level");
 145#endif
 146