]> Git Repo - linux.git/commitdiff
Merge branch 'devel'
authorMauro Carvalho Chehab <[email protected]>
Mon, 30 Jul 2012 00:11:05 +0000 (21:11 -0300)
committerMauro Carvalho Chehab <[email protected]>
Mon, 30 Jul 2012 00:11:05 +0000 (21:11 -0300)
* devel: (33 commits)
  edac i5000, i5400: fix pointer math in i5000_get_mc_regs()
  edac: allow specifying the error count with fake_inject
  edac: add support for Calxeda highbank L2 cache ecc
  edac: add support for Calxeda highbank memory controller
  edac: create top-level debugfs directory
  sb_edac: properly handle error count
  i7core_edac: properly handle error count
  edac: edac_mc_handle_error(): add an error_count parameter
  edac: remove arch-specific parameter for the error handler
  amd64_edac: Don't pass driver name as an error parameter
  edac_mc: check for allocation failure in edac_mc_alloc()
  edac: Increase version to 3.0.0
  edac_mc: Cleanup per-dimm_info debug messages
  edac: Convert debugfX to edac_dbg(X,
  edac: Use more normal debugging macro style
  edac: Don't add __func__ or __FILE__ for debugf[0-9] msgs
  Edac: Add ABI Documentation for the new device nodes
  edac: move documentation ABI to ABI/testing/sysfs-devices-edac
  i7core_edac: change the mem allocation scheme to make Documentation/kobject.txt happy
  edac: change the mem allocation scheme to make Documentation/kobject.txt happy
  ...

1  2 
Documentation/edac.txt
drivers/edac/edac_core.h
drivers/edac/edac_device.c
drivers/edac/edac_mc.c
drivers/edac/i7core_edac.c
drivers/edac/mpc85xx_edac.c
drivers/edac/sb_edac.c

diff --combined Documentation/edac.txt
index 03df2b0203320d3451fad0765bb11e95661392f8,c25f086a696086c3323693b68e9b865042ebd8bb..56c7e936430f172e135ea8d180682167ce907754
@@@ -232,116 -232,20 +232,20 @@@ EDAC control and attribute files
  
  
  In 'mcX' directories are EDAC control and attribute files for
- this 'X' instance of the memory controllers:
- Counter reset control file:
-       'reset_counters'
-       This write-only control file will zero all the statistical counters
-       for UE and CE errors.  Zeroing the counters will also reset the timer
-       indicating how long since the last counter zero.  This is useful
-       for computing errors/time.  Since the counters are always reset at
-       driver initialization time, no module/kernel parameter is available.
-       RUN TIME: echo "anything" >/sys/devices/system/edac/mc/mc0/counter_reset
-               This resets the counters on memory controller 0
- Seconds since last counter reset control file:
-       'seconds_since_reset'
-       This attribute file displays how many seconds have elapsed since the
-       last counter reset. This can be used with the error counters to
-       measure error rates.
- Memory Controller name attribute file:
-       'mc_name'
-       This attribute file displays the type of memory controller
-       that is being utilized.
- Total memory managed by this memory controller attribute file:
-       'size_mb'
-       This attribute file displays, in count of megabytes, of memory
-       that this instance of memory controller manages.
- Total Uncorrectable Errors count attribute file:
-       'ue_count'
-       This attribute file displays the total count of uncorrectable
-       errors that have occurred on this memory controller. If panic_on_ue
-       is set this counter will not have a chance to increment,
-       since EDAC will panic the system.
- Total UE count that had no information attribute fileY:
-       'ue_noinfo_count'
-       This attribute file displays the number of UEs that have occurred
-       with no information as to which DIMM slot is having errors.
- Total Correctable Errors count attribute file:
-       'ce_count'
-       This attribute file displays the total count of correctable
-       errors that have occurred on this memory controller. This
-       count is very important to examine. CEs provide early
-       indications that a DIMM is beginning to fail. This count
-       field should be monitored for non-zero values and report
-       such information to the system administrator.
- Total Correctable Errors count attribute file:
-       'ce_noinfo_count'
-       This attribute file displays the number of CEs that
-       have occurred wherewith no information as to which DIMM slot
-       is having errors. Memory is handicapped, but operational,
-       yet no information is available to indicate which slot
-       the failing memory is in. This count field should be also
-       be monitored for non-zero values.
- Device Symlink:
-       'device'
-       Symlink to the memory controller device.
- Sdram memory scrubbing rate:
-       'sdram_scrub_rate'
-       Read/Write attribute file that controls memory scrubbing. The scrubbing
-       rate is set by writing a minimum bandwidth in bytes/sec to the attribute
-       file. The rate will be translated to an internal value that gives at
-       least the specified rate.
-       Reading the file will return the actual scrubbing rate employed.
-       If configuration fails or memory scrubbing is not implemented, accessing
-       that attribute will fail.
+ this 'X' instance of the memory controllers.
  
+ For a description of the sysfs API, please see:
+       Documentation/ABI/testing/sysfs/devices-edac
  
  
  ============================================================================
  'csrowX' DIRECTORIES
  
+ When CONFIG_EDAC_LEGACY_SYSFS is enabled, the sysfs will contain the
+ csrowX directories. As this API doesn't work properly for Rambus, FB-DIMMs
+ and modern Intel Memory Controllers, this is being deprecated in favor
+ of dimmX directories.
  In the 'csrowX' directories are EDAC control and attribute files for
  this 'X' instance of csrow:
  
@@@ -734,7 -638,7 +638,7 @@@ were done at i7core_edac driver. This c
     associated with a physical CPU socket.
  
     Each MC have 3 physical read channels, 3 physical write channels and
 -   3 logic channels. The driver currenty sees it as just 3 channels.
 +   3 logic channels. The driver currently sees it as just 3 channels.
     Each channel can have up to 3 DIMMs.
  
     The minimum known unity is DIMMs. There are no information about csrows.
diff --combined drivers/edac/edac_core.h
index 117490d4f8359d0fbe9ab50729270e1e0424fe09,3843222e5b9f583b14545def4181875ab3573142..23bb99fa44f1e7ffc6307eeb9d64fbda43f591d4
@@@ -71,26 -71,21 +71,21 @@@ extern const char *edac_mem_types[]
  #ifdef CONFIG_EDAC_DEBUG
  extern int edac_debug_level;
  
- #define edac_debug_printk(level, fmt, arg...)                           \
-       do {                                                            \
-               if (level <= edac_debug_level)                          \
-                       edac_printk(KERN_DEBUG, EDAC_DEBUG,             \
-                                   "%s: " fmt, __func__, ##arg);       \
-       } while (0)
- #define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ )
- #define debugf1( ... ) edac_debug_printk(1, __VA_ARGS__ )
- #define debugf2( ... ) edac_debug_printk(2, __VA_ARGS__ )
- #define debugf3( ... ) edac_debug_printk(3, __VA_ARGS__ )
- #define debugf4( ... ) edac_debug_printk(4, __VA_ARGS__ )
+ #define edac_dbg(level, fmt, ...)                                     \
+ do {                                                                  \
+       if (level <= edac_debug_level)                                  \
+               edac_printk(KERN_DEBUG, EDAC_DEBUG,                     \
+                           "%s: " fmt, __func__, ##__VA_ARGS__);       \
+ } while (0)
  
  #else                         /* !CONFIG_EDAC_DEBUG */
  
- #define debugf0( ... )
- #define debugf1( ... )
- #define debugf2( ... )
- #define debugf3( ... )
- #define debugf4( ... )
+ #define edac_dbg(level, fmt, ...)                                     \
+ do {                                                                  \
+       if (0)                                                          \
+               edac_printk(KERN_DEBUG, EDAC_DEBUG,                     \
+                           "%s: " fmt, __func__, ##__VA_ARGS__);       \
+ } while (0)
  
  #endif                                /* !CONFIG_EDAC_DEBUG */
  
   *
   * CPU caches (L1 and L2)
   * DMA engines
 - * Core CPU swithces
 + * Core CPU switches
   * Fabric switch units
   * PCIe interface controllers
   * other EDAC/ECC type devices that can be monitored for
   * errors, etc.
   *
 - * It allows for a 2 level set of hiearchry. For example:
 + * It allows for a 2 level set of hierarchy. For example:
   *
   * cache could be composed of L1, L2 and L3 levels of cache.
   * Each CPU core would have its own L1 cache, while sharing
@@@ -460,15 -455,15 +455,15 @@@ extern int edac_mc_find_csrow_by_page(s
                                      unsigned long page);
  void edac_mc_handle_error(const enum hw_event_mc_err_type type,
                          struct mem_ctl_info *mci,
+                         const u16 error_count,
                          const unsigned long page_frame_number,
                          const unsigned long offset_in_page,
                          const unsigned long syndrome,
-                         const int layer0,
-                         const int layer1,
-                         const int layer2,
+                         const int top_layer,
+                         const int mid_layer,
+                         const int low_layer,
                          const char *msg,
-                         const char *other_detail,
-                         const void *mcelog);
+                         const char *other_detail);
  
  /*
   * edac_device APIs
index ee3f1f810c1e094c27dbd012d51c4cdfa9b4ee55,9523e76191f26a3825dbf831a75da70d1b10cf8e..211021dfec734a5e5466e2155eaf108ee4ec997c
@@@ -40,12 -40,13 +40,13 @@@ static LIST_HEAD(edac_device_list)
  #ifdef CONFIG_EDAC_DEBUG
  static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev)
  {
-       debugf3("\tedac_dev = %p dev_idx=%d \n", edac_dev, edac_dev->dev_idx);
-       debugf4("\tedac_dev->edac_check = %p\n", edac_dev->edac_check);
-       debugf3("\tdev = %p\n", edac_dev->dev);
-       debugf3("\tmod_name:ctl_name = %s:%s\n",
-               edac_dev->mod_name, edac_dev->ctl_name);
-       debugf3("\tpvt_info = %p\n\n", edac_dev->pvt_info);
+       edac_dbg(3, "\tedac_dev = %p dev_idx=%d\n",
+                edac_dev, edac_dev->dev_idx);
+       edac_dbg(4, "\tedac_dev->edac_check = %p\n", edac_dev->edac_check);
+       edac_dbg(3, "\tdev = %p\n", edac_dev->dev);
+       edac_dbg(3, "\tmod_name:ctl_name = %s:%s\n",
+                edac_dev->mod_name, edac_dev->ctl_name);
+       edac_dbg(3, "\tpvt_info = %p\n\n", edac_dev->pvt_info);
  }
  #endif                                /* CONFIG_EDAC_DEBUG */
  
@@@ -56,7 -57,7 +57,7 @@@
   *
   *    The control structure is allocated in complete chunk
   *    from the OS. It is in turn sub allocated to the
 - *    various objects that compose the struture
 + *    various objects that compose the structure
   *
   *    The structure has a 'nr_instance' array within itself.
   *    Each instance represents a major component
@@@ -82,8 -83,7 +83,7 @@@ struct edac_device_ctl_info *edac_devic
        void *pvt, *p;
        int err;
  
-       debugf4("%s() instances=%d blocks=%d\n",
-               __func__, nr_instances, nr_blocks);
+       edac_dbg(4, "instances=%d blocks=%d\n", nr_instances, nr_blocks);
  
        /* Calculate the size of memory we need to allocate AND
         * determine the offsets of the various item arrays
        /* Name of this edac device */
        snprintf(dev_ctl->name,sizeof(dev_ctl->name),"%s",edac_device_name);
  
-       debugf4("%s() edac_dev=%p next after end=%p\n",
-               __func__, dev_ctl, pvt + sz_private );
+       edac_dbg(4, "edac_dev=%p next after end=%p\n",
+                dev_ctl, pvt + sz_private);
  
        /* Initialize every Instance */
        for (instance = 0; instance < nr_instances; instance++) {
                        snprintf(blk->name, sizeof(blk->name),
                                 "%s%d", edac_block_name, block+offset_value);
  
-                       debugf4("%s() instance=%d inst_p=%p block=#%d "
-                               "block_p=%p name='%s'\n",
-                               __func__, instance, inst, block,
-                               blk, blk->name);
+                       edac_dbg(4, "instance=%d inst_p=%p block=#%d block_p=%p name='%s'\n",
+                                instance, inst, block, blk, blk->name);
  
                        /* if there are NO attributes OR no attribute pointer
                         * then continue on to next block iteration
                        attrib_p = &dev_attrib[block*nr_instances*nr_attrib];
                        blk->block_attributes = attrib_p;
  
-                       debugf4("%s() THIS BLOCK_ATTRIB=%p\n",
-                               __func__, blk->block_attributes);
+                       edac_dbg(4, "THIS BLOCK_ATTRIB=%p\n",
+                                blk->block_attributes);
  
                        /* Initialize every user specified attribute in this
                         * block with the data the caller passed in
  
                                attrib->block = blk;    /* up link */
  
-                               debugf4("%s() alloc-attrib=%p attrib_name='%s' "
-                                       "attrib-spec=%p spec-name=%s\n",
-                                       __func__, attrib, attrib->attr.name,
-                                       &attrib_spec[attr],
-                                       attrib_spec[attr].attr.name
+                               edac_dbg(4, "alloc-attrib=%p attrib_name='%s' attrib-spec=%p spec-name=%s\n",
+                                        attrib, attrib->attr.name,
+                                        &attrib_spec[attr],
+                                        attrib_spec[attr].attr.name
                                        );
                        }
                }
@@@ -273,7 -270,7 +270,7 @@@ static struct edac_device_ctl_info *fin
        struct edac_device_ctl_info *edac_dev;
        struct list_head *item;
  
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
        list_for_each(item, &edac_device_list) {
                edac_dev = list_entry(item, struct edac_device_ctl_info, link);
@@@ -389,7 -386,7 +386,7 @@@ static void edac_device_workq_function(
  
        /* Reschedule the workq for the next time period to start again
         * if the number of msec is for 1 sec, then adjust to the next
 -       * whole one second to save timers fireing all over the period
 +       * whole one second to save timers firing all over the period
         * between integral seconds
         */
        if (edac_dev->poll_msec == 1000)
  void edac_device_workq_setup(struct edac_device_ctl_info *edac_dev,
                                unsigned msec)
  {
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
        /* take the arg 'msec' and set it into the control structure
         * to used in the time period calculation
@@@ -496,7 -493,7 +493,7 @@@ EXPORT_SYMBOL_GPL(edac_device_alloc_ind
   */
  int edac_device_add_device(struct edac_device_ctl_info *edac_dev)
  {
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
  #ifdef CONFIG_EDAC_DEBUG
        if (edac_debug_level >= 3)
@@@ -558,7 -555,7 +555,7 @@@ EXPORT_SYMBOL_GPL(edac_device_add_devic
   *    Remove sysfs entries for specified edac_device structure and
   *    then remove edac_device structure from global list
   *
 - * @pdev:
 + * @dev:
   *    Pointer to 'struct device' representing edac_device
   *    structure to remove.
   *
@@@ -570,7 -567,7 +567,7 @@@ struct edac_device_ctl_info *edac_devic
  {
        struct edac_device_ctl_info *edac_dev;
  
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
        mutex_lock(&device_ctls_mutex);
  
diff --combined drivers/edac/edac_mc.c
index de5ba86e8b8998df830a0e62647378e4667489f4,8d59378f839cdbd9ee31493c99edb0818f49f8a2..616d90bcb3a4106929523c4a98fe32fb27f6a9a6
  #include <linux/list.h>
  #include <linux/ctype.h>
  #include <linux/edac.h>
+ #include <linux/bitops.h>
  #include <asm/uaccess.h>
  #include <asm/page.h>
  #include <asm/edac.h>
  #include "edac_core.h"
  #include "edac_module.h"
  
+ #define CREATE_TRACE_POINTS
+ #define TRACE_INCLUDE_PATH ../../include/ras
+ #include <ras/ras_event.h>
  /* lock to memory controller's control array */
  static DEFINE_MUTEX(mem_ctls_mutex);
  static LIST_HEAD(mc_devices);
  
+ unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
+                                unsigned len)
+ {
+       struct mem_ctl_info *mci = dimm->mci;
+       int i, n, count = 0;
+       char *p = buf;
+       for (i = 0; i < mci->n_layers; i++) {
+               n = snprintf(p, len, "%s %d ",
+                             edac_layer_name[mci->layers[i].type],
+                             dimm->location[i]);
+               p += n;
+               len -= n;
+               count += n;
+               if (!len)
+                       break;
+       }
+       return count;
+ }
  #ifdef CONFIG_EDAC_DEBUG
  
  static void edac_mc_dump_channel(struct rank_info *chan)
  {
-       debugf4("\tchannel = %p\n", chan);
-       debugf4("\tchannel->chan_idx = %d\n", chan->chan_idx);
-       debugf4("\tchannel->csrow = %p\n\n", chan->csrow);
-       debugf4("\tchannel->dimm = %p\n", chan->dimm);
+       edac_dbg(4, "  channel->chan_idx = %d\n", chan->chan_idx);
+       edac_dbg(4, "    channel = %p\n", chan);
+       edac_dbg(4, "    channel->csrow = %p\n", chan->csrow);
+       edac_dbg(4, "    channel->dimm = %p\n", chan->dimm);
  }
  
- static void edac_mc_dump_dimm(struct dimm_info *dimm)
+ static void edac_mc_dump_dimm(struct dimm_info *dimm, int number)
  {
-       int i;
-       debugf4("\tdimm = %p\n", dimm);
-       debugf4("\tdimm->label = '%s'\n", dimm->label);
-       debugf4("\tdimm->nr_pages = 0x%x\n", dimm->nr_pages);
-       debugf4("\tdimm location ");
-       for (i = 0; i < dimm->mci->n_layers; i++) {
-               printk(KERN_CONT "%d", dimm->location[i]);
-               if (i < dimm->mci->n_layers - 1)
-                       printk(KERN_CONT ".");
-       }
-       printk(KERN_CONT "\n");
-       debugf4("\tdimm->grain = %d\n", dimm->grain);
-       debugf4("\tdimm->nr_pages = 0x%x\n", dimm->nr_pages);
+       char location[80];
+       edac_dimm_info_location(dimm, location, sizeof(location));
+       edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n",
+                dimm->mci->mem_is_per_rank ? "rank" : "dimm",
+                number, location, dimm->csrow, dimm->cschannel);
+       edac_dbg(4, "  dimm = %p\n", dimm);
+       edac_dbg(4, "  dimm->label = '%s'\n", dimm->label);
+       edac_dbg(4, "  dimm->nr_pages = 0x%x\n", dimm->nr_pages);
+       edac_dbg(4, "  dimm->grain = %d\n", dimm->grain);
+       edac_dbg(4, "  dimm->nr_pages = 0x%x\n", dimm->nr_pages);
  }
  
  static void edac_mc_dump_csrow(struct csrow_info *csrow)
  {
-       debugf4("\tcsrow = %p\n", csrow);
-       debugf4("\tcsrow->csrow_idx = %d\n", csrow->csrow_idx);
-       debugf4("\tcsrow->first_page = 0x%lx\n", csrow->first_page);
-       debugf4("\tcsrow->last_page = 0x%lx\n", csrow->last_page);
-       debugf4("\tcsrow->page_mask = 0x%lx\n", csrow->page_mask);
-       debugf4("\tcsrow->nr_channels = %d\n", csrow->nr_channels);
-       debugf4("\tcsrow->channels = %p\n", csrow->channels);
-       debugf4("\tcsrow->mci = %p\n\n", csrow->mci);
+       edac_dbg(4, "csrow->csrow_idx = %d\n", csrow->csrow_idx);
+       edac_dbg(4, "  csrow = %p\n", csrow);
+       edac_dbg(4, "  csrow->first_page = 0x%lx\n", csrow->first_page);
+       edac_dbg(4, "  csrow->last_page = 0x%lx\n", csrow->last_page);
+       edac_dbg(4, "  csrow->page_mask = 0x%lx\n", csrow->page_mask);
+       edac_dbg(4, "  csrow->nr_channels = %d\n", csrow->nr_channels);
+       edac_dbg(4, "  csrow->channels = %p\n", csrow->channels);
+       edac_dbg(4, "  csrow->mci = %p\n", csrow->mci);
  }
  
  static void edac_mc_dump_mci(struct mem_ctl_info *mci)
  {
-       debugf3("\tmci = %p\n", mci);
-       debugf3("\tmci->mtype_cap = %lx\n", mci->mtype_cap);
-       debugf3("\tmci->edac_ctl_cap = %lx\n", mci->edac_ctl_cap);
-       debugf3("\tmci->edac_cap = %lx\n", mci->edac_cap);
-       debugf4("\tmci->edac_check = %p\n", mci->edac_check);
-       debugf3("\tmci->nr_csrows = %d, csrows = %p\n",
-               mci->nr_csrows, mci->csrows);
-       debugf3("\tmci->nr_dimms = %d, dimms = %p\n",
-               mci->tot_dimms, mci->dimms);
-       debugf3("\tdev = %p\n", mci->dev);
-       debugf3("\tmod_name:ctl_name = %s:%s\n", mci->mod_name, mci->ctl_name);
-       debugf3("\tpvt_info = %p\n\n", mci->pvt_info);
+       edac_dbg(3, "\tmci = %p\n", mci);
+       edac_dbg(3, "\tmci->mtype_cap = %lx\n", mci->mtype_cap);
+       edac_dbg(3, "\tmci->edac_ctl_cap = %lx\n", mci->edac_ctl_cap);
+       edac_dbg(3, "\tmci->edac_cap = %lx\n", mci->edac_cap);
+       edac_dbg(4, "\tmci->edac_check = %p\n", mci->edac_check);
+       edac_dbg(3, "\tmci->nr_csrows = %d, csrows = %p\n",
+                mci->nr_csrows, mci->csrows);
+       edac_dbg(3, "\tmci->nr_dimms = %d, dimms = %p\n",
+                mci->tot_dimms, mci->dimms);
+       edac_dbg(3, "\tdev = %p\n", mci->pdev);
+       edac_dbg(3, "\tmod_name:ctl_name = %s:%s\n",
+                mci->mod_name, mci->ctl_name);
+       edac_dbg(3, "\tpvt_info = %p\n\n", mci->pvt_info);
  }
  
  #endif                                /* CONFIG_EDAC_DEBUG */
@@@ -164,7 -189,7 +189,7 @@@ void *edac_align_ptr(void **p, unsigne
        else
                return (char *)ptr;
  
 -      r = size % align;
 +      r = (unsigned long)p % align;
  
        if (r == 0)
                return (char *)ptr;
@@@ -205,15 -230,15 +230,15 @@@ struct mem_ctl_info *edac_mc_alloc(unsi
  {
        struct mem_ctl_info *mci;
        struct edac_mc_layer *layer;
-       struct csrow_info *csi, *csr;
-       struct rank_info *chi, *chp, *chan;
+       struct csrow_info *csr;
+       struct rank_info *chan;
        struct dimm_info *dimm;
        u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
        unsigned pos[EDAC_MAX_LAYERS];
        unsigned size, tot_dimms = 1, count = 1;
        unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
        void *pvt, *p, *ptr = NULL;
-       int i, j, err, row, chn, n, len;
+       int i, j, row, chn, n, len, off;
        bool per_rank = false;
  
        BUG_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0);
         */
        mci = edac_align_ptr(&ptr, sizeof(*mci), 1);
        layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers);
-       csi = edac_align_ptr(&ptr, sizeof(*csi), tot_csrows);
-       chi = edac_align_ptr(&ptr, sizeof(*chi), tot_csrows * tot_channels);
-       dimm = edac_align_ptr(&ptr, sizeof(*dimm), tot_dimms);
        for (i = 0; i < n_layers; i++) {
                count *= layers[i].size;
-               debugf4("%s: errcount layer %d size %d\n", __func__, i, count);
+               edac_dbg(4, "errcount layer %d size %d\n", i, count);
                ce_per_layer[i] = edac_align_ptr(&ptr, sizeof(u32), count);
                ue_per_layer[i] = edac_align_ptr(&ptr, sizeof(u32), count);
                tot_errcount += 2 * count;
        }
  
-       debugf4("%s: allocating %d error counters\n", __func__, tot_errcount);
+       edac_dbg(4, "allocating %d error counters\n", tot_errcount);
        pvt = edac_align_ptr(&ptr, sz_pvt, 1);
        size = ((unsigned long)pvt) + sz_pvt;
  
-       debugf1("%s(): allocating %u bytes for mci data (%d %s, %d csrows/channels)\n",
-               __func__, size,
-               tot_dimms,
-               per_rank ? "ranks" : "dimms",
-               tot_csrows * tot_channels);
+       edac_dbg(1, "allocating %u bytes for mci data (%d %s, %d csrows/channels)\n",
+                size,
+                tot_dimms,
+                per_rank ? "ranks" : "dimms",
+                tot_csrows * tot_channels);
        mci = kzalloc(size, GFP_KERNEL);
        if (mci == NULL)
                return NULL;
         * rather than an imaginary chunk of memory located at address 0.
         */
        layer = (struct edac_mc_layer *)(((char *)mci) + ((unsigned long)layer));
-       csi = (struct csrow_info *)(((char *)mci) + ((unsigned long)csi));
-       chi = (struct rank_info *)(((char *)mci) + ((unsigned long)chi));
-       dimm = (struct dimm_info *)(((char *)mci) + ((unsigned long)dimm));
        for (i = 0; i < n_layers; i++) {
                mci->ce_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ce_per_layer[i]));
                mci->ue_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ue_per_layer[i]));
  
        /* setup index and various internal pointers */
        mci->mc_idx = mc_num;
-       mci->csrows = csi;
-       mci->dimms  = dimm;
        mci->tot_dimms = tot_dimms;
        mci->pvt_info = pvt;
        mci->n_layers = n_layers;
        mci->mem_is_per_rank = per_rank;
  
        /*
-        * Fill the csrow struct
+        * Alocate and fill the csrow/channels structs
         */
+       mci->csrows = kcalloc(sizeof(*mci->csrows), tot_csrows, GFP_KERNEL);
+       if (!mci->csrows)
+               goto error;
        for (row = 0; row < tot_csrows; row++) {
-               csr = &csi[row];
+               csr = kzalloc(sizeof(**mci->csrows), GFP_KERNEL);
+               if (!csr)
+                       goto error;
+               mci->csrows[row] = csr;
                csr->csrow_idx = row;
                csr->mci = mci;
                csr->nr_channels = tot_channels;
-               chp = &chi[row * tot_channels];
-               csr->channels = chp;
+               csr->channels = kcalloc(sizeof(*csr->channels), tot_channels,
+                                       GFP_KERNEL);
+               if (!csr->channels)
+                       goto error;
  
                for (chn = 0; chn < tot_channels; chn++) {
-                       chan = &chp[chn];
+                       chan = kzalloc(sizeof(**csr->channels), GFP_KERNEL);
+                       if (!chan)
+                               goto error;
+                       csr->channels[chn] = chan;
                        chan->chan_idx = chn;
                        chan->csrow = csr;
                }
        }
  
        /*
-        * Fill the dimm struct
+        * Allocate and fill the dimm structs
         */
+       mci->dimms  = kcalloc(sizeof(*mci->dimms), tot_dimms, GFP_KERNEL);
+       if (!mci->dimms)
+               goto error;
        memset(&pos, 0, sizeof(pos));
        row = 0;
        chn = 0;
-       debugf4("%s: initializing %d %s\n", __func__, tot_dimms,
-               per_rank ? "ranks" : "dimms");
        for (i = 0; i < tot_dimms; i++) {
-               chan = &csi[row].channels[chn];
-               dimm = EDAC_DIMM_PTR(layer, mci->dimms, n_layers,
-                              pos[0], pos[1], pos[2]);
-               dimm->mci = mci;
+               chan = mci->csrows[row]->channels[chn];
+               off = EDAC_DIMM_OFF(layer, n_layers, pos[0], pos[1], pos[2]);
+               if (off < 0 || off >= tot_dimms) {
+                       edac_mc_printk(mci, KERN_ERR, "EDAC core bug: EDAC_DIMM_OFF is trying to do an illegal data access\n");
+                       goto error;
+               }
  
-               debugf2("%s: %d: %s%zd (%d:%d:%d): row %d, chan %d\n", __func__,
-                       i, per_rank ? "rank" : "dimm", (dimm - mci->dimms),
-                       pos[0], pos[1], pos[2], row, chn);
+               dimm = kzalloc(sizeof(**mci->dimms), GFP_KERNEL);
+               if (!dimm)
+                       goto error;
+               mci->dimms[off] = dimm;
+               dimm->mci = mci;
  
                /*
                 * Copy DIMM location and initialize it.
        }
  
        mci->op_state = OP_ALLOC;
-       INIT_LIST_HEAD(&mci->grp_kobj_list);
-       /*
-        * Initialize the 'root' kobj for the edac_mc controller
-        */
-       err = edac_mc_register_sysfs_main_kobj(mci);
-       if (err) {
-               kfree(mci);
-               return NULL;
-       }
  
        /* at this point, the root kobj is valid, and in order to
         * 'free' the object, then the function:
         * which will perform kobj unregistration and the actual free
         * will occur during the kobject callback operation
         */
        return mci;
+ error:
+       if (mci->dimms) {
+               for (i = 0; i < tot_dimms; i++)
+                       kfree(mci->dimms[i]);
+               kfree(mci->dimms);
+       }
+       if (mci->csrows) {
+               for (chn = 0; chn < tot_channels; chn++) {
+                       csr = mci->csrows[chn];
+                       if (csr) {
+                               for (chn = 0; chn < tot_channels; chn++)
+                                       kfree(csr->channels[chn]);
+                               kfree(csr);
+                       }
+                       kfree(mci->csrows[i]);
+               }
+               kfree(mci->csrows);
+       }
+       kfree(mci);
+       return NULL;
  }
  EXPORT_SYMBOL_GPL(edac_mc_alloc);
  
   */
  void edac_mc_free(struct mem_ctl_info *mci)
  {
-       debugf1("%s()\n", __func__);
+       edac_dbg(1, "\n");
  
-       edac_mc_unregister_sysfs_main_kobj(mci);
-       /* free the mci instance memory here */
-       kfree(mci);
+       /* the mci instance is freed here, when the sysfs object is dropped */
+       edac_unregister_sysfs(mci);
  }
  EXPORT_SYMBOL_GPL(edac_mc_free);
  
@@@ -417,12 -463,12 +463,12 @@@ struct mem_ctl_info *find_mci_by_dev(st
        struct mem_ctl_info *mci;
        struct list_head *item;
  
-       debugf3("%s()\n", __func__);
+       edac_dbg(3, "\n");
  
        list_for_each(item, &mc_devices) {
                mci = list_entry(item, struct mem_ctl_info, link);
  
-               if (mci->dev == dev)
+               if (mci->pdev == dev)
                        return mci;
        }
  
@@@ -485,7 -531,7 +531,7 @@@ static void edac_mc_workq_function(stru
   */
  static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec)
  {
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
        /* if this instance is not in the POLL state, then simply return */
        if (mci->op_state != OP_RUNNING_POLL)
@@@ -512,8 -558,7 +558,7 @@@ static void edac_mc_workq_teardown(stru
  
        status = cancel_delayed_work(&mci->work);
        if (status == 0) {
-               debugf0("%s() not canceled, flush the queue\n",
-                       __func__);
+               edac_dbg(0, "not canceled, flush the queue\n");
  
                /* workq instance might be running, wait for it */
                flush_workqueue(edac_workqueue);
@@@ -574,7 -619,7 +619,7 @@@ static int add_mc_to_global_list(struc
  
        insert_before = &mc_devices;
  
-       p = find_mci_by_dev(mci->dev);
+       p = find_mci_by_dev(mci->pdev);
        if (unlikely(p != NULL))
                goto fail0;
  
  
  fail0:
        edac_printk(KERN_WARNING, EDAC_MC,
-               "%s (%s) %s %s already assigned %d\n", dev_name(p->dev),
+               "%s (%s) %s %s already assigned %d\n", dev_name(p->pdev),
                edac_dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx);
        return 1;
  
@@@ -660,7 -705,7 +705,7 @@@ EXPORT_SYMBOL(edac_mc_find)
  /* FIXME - should a warning be printed if no error detection? correction? */
  int edac_mc_add_mc(struct mem_ctl_info *mci)
  {
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
  #ifdef CONFIG_EDAC_DEBUG
        if (edac_debug_level >= 3)
                int i;
  
                for (i = 0; i < mci->nr_csrows; i++) {
+                       struct csrow_info *csrow = mci->csrows[i];
+                       u32 nr_pages = 0;
                        int j;
  
-                       edac_mc_dump_csrow(&mci->csrows[i]);
-                       for (j = 0; j < mci->csrows[i].nr_channels; j++)
-                               edac_mc_dump_channel(&mci->csrows[i].
-                                               channels[j]);
+                       for (j = 0; j < csrow->nr_channels; j++)
+                               nr_pages += csrow->channels[j]->dimm->nr_pages;
+                       if (!nr_pages)
+                               continue;
+                       edac_mc_dump_csrow(csrow);
+                       for (j = 0; j < csrow->nr_channels; j++)
+                               if (csrow->channels[j]->dimm->nr_pages)
+                                       edac_mc_dump_channel(csrow->channels[j]);
                }
                for (i = 0; i < mci->tot_dimms; i++)
-                       edac_mc_dump_dimm(&mci->dimms[i]);
+                       if (mci->dimms[i]->nr_pages)
+                               edac_mc_dump_dimm(mci->dimms[i], i);
        }
  #endif
        mutex_lock(&mem_ctls_mutex);
@@@ -732,7 -784,7 +784,7 @@@ struct mem_ctl_info *edac_mc_del_mc(str
  {
        struct mem_ctl_info *mci;
  
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
        mutex_lock(&mem_ctls_mutex);
  
@@@ -770,7 -822,7 +822,7 @@@ static void edac_mc_scrub_block(unsigne
        void *virt_addr;
        unsigned long flags = 0;
  
-       debugf3("%s()\n", __func__);
+       edac_dbg(3, "\n");
  
        /* ECC error page was not in our memory. Ignore it. */
        if (!pfn_valid(page))
  /* FIXME - should return -1 */
  int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page)
  {
-       struct csrow_info *csrows = mci->csrows;
+       struct csrow_info **csrows = mci->csrows;
        int row, i, j, n;
  
-       debugf1("MC%d: %s(): 0x%lx\n", mci->mc_idx, __func__, page);
+       edac_dbg(1, "MC%d: 0x%lx\n", mci->mc_idx, page);
        row = -1;
  
        for (i = 0; i < mci->nr_csrows; i++) {
-               struct csrow_info *csrow = &csrows[i];
+               struct csrow_info *csrow = csrows[i];
                n = 0;
                for (j = 0; j < csrow->nr_channels; j++) {
-                       struct dimm_info *dimm = csrow->channels[j].dimm;
+                       struct dimm_info *dimm = csrow->channels[j]->dimm;
                        n += dimm->nr_pages;
                }
                if (n == 0)
                        continue;
  
-               debugf3("MC%d: %s(): first(0x%lx) page(0x%lx) last(0x%lx) "
-                       "mask(0x%lx)\n", mci->mc_idx, __func__,
-                       csrow->first_page, page, csrow->last_page,
-                       csrow->page_mask);
+               edac_dbg(3, "MC%d: first(0x%lx) page(0x%lx) last(0x%lx) mask(0x%lx)\n",
+                        mci->mc_idx,
+                        csrow->first_page, page, csrow->last_page,
+                        csrow->page_mask);
  
                if ((page >= csrow->first_page) &&
                    (page <= csrow->last_page) &&
@@@ -845,15 -897,16 +897,16 @@@ const char *edac_layer_name[] = 
  EXPORT_SYMBOL_GPL(edac_layer_name);
  
  static void edac_inc_ce_error(struct mem_ctl_info *mci,
-                                   bool enable_per_layer_report,
-                                   const int pos[EDAC_MAX_LAYERS])
+                             bool enable_per_layer_report,
+                             const int pos[EDAC_MAX_LAYERS],
+                             const u16 count)
  {
        int i, index = 0;
  
-       mci->ce_mc++;
+       mci->ce_mc += count;
  
        if (!enable_per_layer_report) {
-               mci->ce_noinfo_count++;
+               mci->ce_noinfo_count += count;
                return;
        }
  
                if (pos[i] < 0)
                        break;
                index += pos[i];
-               mci->ce_per_layer[i][index]++;
+               mci->ce_per_layer[i][index] += count;
  
                if (i < mci->n_layers - 1)
                        index *= mci->layers[i + 1].size;
  
  static void edac_inc_ue_error(struct mem_ctl_info *mci,
                                    bool enable_per_layer_report,
-                                   const int pos[EDAC_MAX_LAYERS])
+                                   const int pos[EDAC_MAX_LAYERS],
+                                   const u16 count)
  {
        int i, index = 0;
  
-       mci->ue_mc++;
+       mci->ue_mc += count;
  
        if (!enable_per_layer_report) {
-               mci->ce_noinfo_count++;
+               mci->ce_noinfo_count += count;
                return;
        }
  
                if (pos[i] < 0)
                        break;
                index += pos[i];
-               mci->ue_per_layer[i][index]++;
+               mci->ue_per_layer[i][index] += count;
  
                if (i < mci->n_layers - 1)
                        index *= mci->layers[i + 1].size;
  }
  
  static void edac_ce_error(struct mem_ctl_info *mci,
+                         const u16 error_count,
                          const int pos[EDAC_MAX_LAYERS],
                          const char *msg,
                          const char *location,
                          const bool enable_per_layer_report,
                          const unsigned long page_frame_number,
                          const unsigned long offset_in_page,
-                         u32 grain)
+                         long grain)
  {
        unsigned long remapped_page;
  
        if (edac_mc_get_log_ce()) {
                if (other_detail && *other_detail)
                        edac_mc_printk(mci, KERN_WARNING,
-                                      "CE %s on %s (%s%s - %s)\n",
+                                      "%d CE %s on %s (%s %s - %s)\n",
+                                      error_count,
                                       msg, label, location,
                                       detail, other_detail);
                else
                        edac_mc_printk(mci, KERN_WARNING,
-                                      "CE %s on %s (%s%s)\n",
+                                      "%d CE %s on %s (%s %s)\n",
+                                      error_count,
                                       msg, label, location,
                                       detail);
        }
-       edac_inc_ce_error(mci, enable_per_layer_report, pos);
+       edac_inc_ce_error(mci, enable_per_layer_report, pos, error_count);
  
        if (mci->scrub_mode & SCRUB_SW_SRC) {
                /*
  }
  
  static void edac_ue_error(struct mem_ctl_info *mci,
+                         const u16 error_count,
                          const int pos[EDAC_MAX_LAYERS],
                          const char *msg,
                          const char *location,
        if (edac_mc_get_log_ue()) {
                if (other_detail && *other_detail)
                        edac_mc_printk(mci, KERN_WARNING,
-                                      "UE %s on %s (%s%s - %s)\n",
+                                      "%d UE %s on %s (%s %s - %s)\n",
+                                      error_count,
                                       msg, label, location, detail,
                                       other_detail);
                else
                        edac_mc_printk(mci, KERN_WARNING,
-                                      "UE %s on %s (%s%s)\n",
+                                      "%d UE %s on %s (%s %s)\n",
+                                      error_count,
                                       msg, label, location, detail);
        }
  
                              msg, label, location, detail);
        }
  
-       edac_inc_ue_error(mci, enable_per_layer_report, pos);
+       edac_inc_ue_error(mci, enable_per_layer_report, pos, error_count);
  }
  
  #define OTHER_LABEL " or "
+ /**
+  * edac_mc_handle_error - reports a memory event to userspace
+  *
+  * @type:             severity of the error (CE/UE/Fatal)
+  * @mci:              a struct mem_ctl_info pointer
+  * @error_count:      Number of errors of the same type
+  * @page_frame_number:        mem page where the error occurred
+  * @offset_in_page:   offset of the error inside the page
+  * @syndrome:         ECC syndrome
+  * @top_layer:                Memory layer[0] position
+  * @mid_layer:                Memory layer[1] position
+  * @low_layer:                Memory layer[2] position
+  * @msg:              Message meaningful to the end users that
+  *                    explains the event
+  * @other_detail:     Technical details about the event that
+  *                    may help hardware manufacturers and
+  *                    EDAC developers to analyse the event
+  */
  void edac_mc_handle_error(const enum hw_event_mc_err_type type,
                          struct mem_ctl_info *mci,
+                         const u16 error_count,
                          const unsigned long page_frame_number,
                          const unsigned long offset_in_page,
                          const unsigned long syndrome,
-                         const int layer0,
-                         const int layer1,
-                         const int layer2,
+                         const int top_layer,
+                         const int mid_layer,
+                         const int low_layer,
                          const char *msg,
-                         const char *other_detail,
-                         const void *mcelog)
+                         const char *other_detail)
  {
        /* FIXME: too much for stack: move it to some pre-alocated area */
        char detail[80], location[80];
        char label[(EDAC_MC_LABEL_LEN + 1 + sizeof(OTHER_LABEL)) * mci->tot_dimms];
        char *p;
        int row = -1, chan = -1;
-       int pos[EDAC_MAX_LAYERS] = { layer0, layer1, layer2 };
+       int pos[EDAC_MAX_LAYERS] = { top_layer, mid_layer, low_layer };
        int i;
-       u32 grain;
+       long grain;
        bool enable_per_layer_report = false;
+       u8 grain_bits;
  
-       debugf3("MC%d: %s()\n", mci->mc_idx, __func__);
+       edac_dbg(3, "MC%d\n", mci->mc_idx);
  
        /*
         * Check if the event report is consistent and if the memory
        p = label;
        *p = '\0';
        for (i = 0; i < mci->tot_dimms; i++) {
-               struct dimm_info *dimm = &mci->dimms[i];
+               struct dimm_info *dimm = mci->dimms[i];
  
-               if (layer0 >= 0 && layer0 != dimm->location[0])
+               if (top_layer >= 0 && top_layer != dimm->location[0])
                        continue;
-               if (layer1 >= 0 && layer1 != dimm->location[1])
+               if (mid_layer >= 0 && mid_layer != dimm->location[1])
                        continue;
-               if (layer2 >= 0 && layer2 != dimm->location[2])
+               if (low_layer >= 0 && low_layer != dimm->location[2])
                        continue;
  
                /* get the max grain, over the error match range */
                         * get csrow/channel of the DIMM, in order to allow
                         * incrementing the compat API counters
                         */
-                       debugf4("%s: %s csrows map: (%d,%d)\n",
-                               __func__,
-                               mci->mem_is_per_rank ? "rank" : "dimm",
-                               dimm->csrow, dimm->cschannel);
+                       edac_dbg(4, "%s csrows map: (%d,%d)\n",
+                                mci->mem_is_per_rank ? "rank" : "dimm",
+                                dimm->csrow, dimm->cschannel);
                        if (row == -1)
                                row = dimm->csrow;
                        else if (row >= 0 && row != dimm->csrow)
        if (!enable_per_layer_report) {
                strcpy(label, "any memory");
        } else {
-               debugf4("%s: csrow/channel to increment: (%d,%d)\n",
-                       __func__, row, chan);
+               edac_dbg(4, "csrow/channel to increment: (%d,%d)\n", row, chan);
                if (p == label)
                        strcpy(label, "unknown memory");
                if (type == HW_EVENT_ERR_CORRECTED) {
                        if (row >= 0) {
-                               mci->csrows[row].ce_count++;
+                               mci->csrows[row]->ce_count += error_count;
                                if (chan >= 0)
-                                       mci->csrows[row].channels[chan].ce_count++;
+                                       mci->csrows[row]->channels[chan]->ce_count += error_count;
                        }
                } else
                        if (row >= 0)
-                               mci->csrows[row].ue_count++;
+                               mci->csrows[row]->ue_count += error_count;
        }
  
        /* Fill the RAM location data */
                             edac_layer_name[mci->layers[i].type],
                             pos[i]);
        }
+       if (p > location)
+               *(p - 1) = '\0';
+       /* Report the error via the trace interface */
+       grain_bits = fls_long(grain) + 1;
+       trace_mc_event(type, msg, label, error_count,
+                      mci->mc_idx, top_layer, mid_layer, low_layer,
+                      PAGES_TO_MiB(page_frame_number) | offset_in_page,
+                      grain_bits, syndrome, other_detail);
  
        /* Memory type dependent details about the error */
        if (type == HW_EVENT_ERR_CORRECTED) {
                snprintf(detail, sizeof(detail),
-                       "page:0x%lx offset:0x%lx grain:%d syndrome:0x%lx",
+                       "page:0x%lx offset:0x%lx grain:%ld syndrome:0x%lx",
                        page_frame_number, offset_in_page,
                        grain, syndrome);
-               edac_ce_error(mci, pos, msg, location, label, detail,
-                             other_detail, enable_per_layer_report,
+               edac_ce_error(mci, error_count, pos, msg, location, label,
+                             detail, other_detail, enable_per_layer_report,
                              page_frame_number, offset_in_page, grain);
        } else {
                snprintf(detail, sizeof(detail),
-                       "page:0x%lx offset:0x%lx grain:%d",
+                       "page:0x%lx offset:0x%lx grain:%ld",
                        page_frame_number, offset_in_page, grain);
  
-               edac_ue_error(mci, pos, msg, location, label, detail,
-                             other_detail, enable_per_layer_report);
+               edac_ue_error(mci, error_count, pos, msg, location, label,
+                             detail, other_detail, enable_per_layer_report);
        }
  }
  EXPORT_SYMBOL_GPL(edac_mc_handle_error);
index a499c7ed820ae62d8fc489478ef8522e756d833b,a3c9a37b4cc1ee97446156b4df9db0247118935c..3672101023bd8d44c7fb136601a72a0290a9e936
@@@ -90,7 -90,7 +90,7 @@@ MODULE_PARM_DESC(use_pci_fixup, "Enabl
  #define MC_MAX_DOD    0x64
  
  /*
 - * OFFSETS for Device 3 Function 4, as inicated on Xeon 5500 datasheet:
 + * OFFSETS for Device 3 Function 4, as indicated on Xeon 5500 datasheet:
   * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
   */
  
    #define DIMM1_COR_ERR(r)                    (((r) >> 16) & 0x7fff)
    #define DIMM0_COR_ERR(r)                    ((r) & 0x7fff)
  
 -/* OFFSETS for Device 3 Function 2, as inicated on Xeon 5500 datasheet */
 +/* OFFSETS for Device 3 Function 2, as indicated on Xeon 5500 datasheet */
  #define MC_SSRCONTROL         0x48
    #define SSR_MODE_DISABLE    0x00
    #define SSR_MODE_ENABLE     0x01
@@@ -248,6 -248,8 +248,8 @@@ struct i7core_dev 
  };
  
  struct i7core_pvt {
+       struct device *addrmatch_dev, *chancounts_dev;
        struct pci_dev  *pci_noncore;
        struct pci_dev  *pci_mcr[MAX_MCR_FUNC + 1];
        struct pci_dev  *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1];
@@@ -399,7 -401,7 +401,7 @@@ static DEFINE_PCI_DEVICE_TABLE(i7core_p
  };
  
  /****************************************************************************
 -                      Anciliary status routines
 +                      Ancillary status routines
   ****************************************************************************/
  
        /* MC_CONTROL bits */
@@@ -514,29 -516,28 +516,28 @@@ static int get_dimm_config(struct mem_c
        pci_read_config_dword(pdev, MC_MAX_DOD, &pvt->info.max_dod);
        pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map);
  
-       debugf0("QPI %d control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
-               pvt->i7core_dev->socket, pvt->info.mc_control, pvt->info.mc_status,
-               pvt->info.max_dod, pvt->info.ch_map);
+       edac_dbg(0, "QPI %d control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
+                pvt->i7core_dev->socket, pvt->info.mc_control,
+                pvt->info.mc_status, pvt->info.max_dod, pvt->info.ch_map);
  
        if (ECC_ENABLED(pvt)) {
-               debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4);
+               edac_dbg(0, "ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4);
                if (ECCx8(pvt))
                        mode = EDAC_S8ECD8ED;
                else
                        mode = EDAC_S4ECD4ED;
        } else {
-               debugf0("ECC disabled\n");
+               edac_dbg(0, "ECC disabled\n");
                mode = EDAC_NONE;
        }
  
        /* FIXME: need to handle the error codes */
-       debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked "
-               "x%x x 0x%x\n",
-               numdimms(pvt->info.max_dod),
-               numrank(pvt->info.max_dod >> 2),
-               numbank(pvt->info.max_dod >> 4),
-               numrow(pvt->info.max_dod >> 6),
-               numcol(pvt->info.max_dod >> 9));
+       edac_dbg(0, "DOD Max limits: DIMMS: %d, %d-ranked, %d-banked x%x x 0x%x\n",
+                numdimms(pvt->info.max_dod),
+                numrank(pvt->info.max_dod >> 2),
+                numbank(pvt->info.max_dod >> 4),
+                numrow(pvt->info.max_dod >> 6),
+                numcol(pvt->info.max_dod >> 9));
  
        for (i = 0; i < NUM_CHANS; i++) {
                u32 data, dimm_dod[3], value[8];
                        continue;
  
                if (!CH_ACTIVE(pvt, i)) {
-                       debugf0("Channel %i is not active\n", i);
+                       edac_dbg(0, "Channel %i is not active\n", i);
                        continue;
                }
                if (CH_DISABLED(pvt, i)) {
-                       debugf0("Channel %i is disabled\n", i);
+                       edac_dbg(0, "Channel %i is disabled\n", i);
                        continue;
                }
  
                pci_read_config_dword(pvt->pci_ch[i][1],
                                MC_DOD_CH_DIMM2, &dimm_dod[2]);
  
-               debugf0("Ch%d phy rd%d, wr%d (0x%08x): "
-                       "%s%s%s%cDIMMs\n",
-                       i,
-                       RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i),
-                       data,
-                       pvt->channel[i].is_3dimms_present ? "3DIMMS " : "",
-                       pvt->channel[i].is_3dimms_present ? "SINGLE_4R " : "",
-                       pvt->channel[i].has_4rank ? "HAS_4R " : "",
-                       (data & REGISTERED_DIMM) ? 'R' : 'U');
+               edac_dbg(0, "Ch%d phy rd%d, wr%d (0x%08x): %s%s%s%cDIMMs\n",
+                        i,
+                        RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i),
+                        data,
+                        pvt->channel[i].is_3dimms_present ? "3DIMMS " : "",
+                        pvt->channel[i].is_3dimms_present ? "SINGLE_4R " : "",
+                        pvt->channel[i].has_4rank ? "HAS_4R " : "",
+                        (data & REGISTERED_DIMM) ? 'R' : 'U');
  
                for (j = 0; j < 3; j++) {
                        u32 banks, ranks, rows, cols;
                        /* DDR3 has 8 I/O banks */
                        size = (rows * cols * banks * ranks) >> (20 - 3);
  
-                       debugf0("\tdimm %d %d Mb offset: %x, "
-                               "bank: %d, rank: %d, row: %#x, col: %#x\n",
-                               j, size,
-                               RANKOFFSET(dimm_dod[j]),
-                               banks, ranks, rows, cols);
+                       edac_dbg(0, "\tdimm %d %d Mb offset: %x, bank: %d, rank: %d, row: %#x, col: %#x\n",
+                                j, size,
+                                RANKOFFSET(dimm_dod[j]),
+                                banks, ranks, rows, cols);
  
                        npages = MiB_TO_PAGES(size);
  
                pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]);
                pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]);
                pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]);
-               debugf1("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i);
+               edac_dbg(1, "\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i);
                for (j = 0; j < 8; j++)
-                       debugf1("\t\t%#x\t%#x\t%#x\n",
-                               (value[j] >> 27) & 0x1,
-                               (value[j] >> 24) & 0x7,
-                               (value[j] & ((1 << 24) - 1)));
+                       edac_dbg(1, "\t\t%#x\t%#x\t%#x\n",
+                                (value[j] >> 27) & 0x1,
+                                (value[j] >> 24) & 0x7,
+                                (value[j] & ((1 << 24) - 1)));
        }
  
        return 0;
                        Error insertion routines
   ****************************************************************************/
  
+ #define to_mci(k) container_of(k, struct mem_ctl_info, dev)
  /* The i7core has independent error injection features per channel.
     However, to have a simpler code, we don't allow enabling error injection
     on more than one channel.
@@@ -691,9 -692,11 +692,11 @@@ static int disable_inject(const struct 
   *    bit 0 - refers to the lower 32-byte half cacheline
   *    bit 1 - refers to the upper 32-byte half cacheline
   */
- static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci,
+ static ssize_t i7core_inject_section_store(struct device *dev,
+                                          struct device_attribute *mattr,
                                           const char *data, size_t count)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct i7core_pvt *pvt = mci->pvt_info;
        unsigned long value;
        int rc;
        return count;
  }
  
- static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci,
-                                             char *data)
+ static ssize_t i7core_inject_section_show(struct device *dev,
+                                         struct device_attribute *mattr,
+                                         char *data)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct i7core_pvt *pvt = mci->pvt_info;
        return sprintf(data, "0x%08x\n", pvt->inject.section);
  }
   *    bit 1 - inject ECC error
   *    bit 2 - inject parity error
   */
- static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci,
+ static ssize_t i7core_inject_type_store(struct device *dev,
+                                       struct device_attribute *mattr,
                                        const char *data, size_t count)
  {
-       struct i7core_pvt *pvt = mci->pvt_info;
+       struct mem_ctl_info *mci = to_mci(dev);
+ struct i7core_pvt *pvt = mci->pvt_info;
        unsigned long value;
        int rc;
  
        return count;
  }
  
- static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci,
-                                             char *data)
+ static ssize_t i7core_inject_type_show(struct device *dev,
+                                      struct device_attribute *mattr,
+                                      char *data)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct i7core_pvt *pvt = mci->pvt_info;
        return sprintf(data, "0x%08x\n", pvt->inject.type);
  }
  
   *   23:16 and 31:24). Flipping bits in two symbol pairs will cause an
   *   uncorrectable error to be injected.
   */
- static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci,
-                                       const char *data, size_t count)
+ static ssize_t i7core_inject_eccmask_store(struct device *dev,
+                                          struct device_attribute *mattr,
+                                          const char *data, size_t count)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct i7core_pvt *pvt = mci->pvt_info;
        unsigned long value;
        int rc;
        return count;
  }
  
- static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci,
-                                             char *data)
+ static ssize_t i7core_inject_eccmask_show(struct device *dev,
+                                         struct device_attribute *mattr,
+                                         char *data)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct i7core_pvt *pvt = mci->pvt_info;
        return sprintf(data, "0x%08x\n", pvt->inject.eccmask);
  }
  
  
  #define DECLARE_ADDR_MATCH(param, limit)                      \
  static ssize_t i7core_inject_store_##param(                   \
-               struct mem_ctl_info *mci,                       \
-               const char *data, size_t count)                 \
+       struct device *dev,                                     \
+       struct device_attribute *mattr,                         \
+       const char *data, size_t count)                         \
  {                                                             \
+       struct mem_ctl_info *mci = to_mci(dev);                 \
        struct i7core_pvt *pvt;                                 \
        long value;                                             \
        int rc;                                                 \
                                                                \
-       debugf1("%s()\n", __func__);                            \
+       edac_dbg(1, "\n");                                      \
        pvt = mci->pvt_info;                                    \
                                                                \
        if (pvt->inject.enable)                                 \
  }                                                             \
                                                                \
  static ssize_t i7core_inject_show_##param(                    \
-               struct mem_ctl_info *mci,                       \
-               char *data)                                     \
+       struct device *dev,                                     \
+       struct device_attribute *mattr,                         \
+       char *data)                                             \
  {                                                             \
+       struct mem_ctl_info *mci = to_mci(dev);                 \
        struct i7core_pvt *pvt;                                 \
                                                                \
        pvt = mci->pvt_info;                                    \
-       debugf1("%s() pvt=%p\n", __func__, pvt);                \
+       edac_dbg(1, "pvt=%p\n", pvt);                           \
        if (pvt->inject.param < 0)                              \
                return sprintf(data, "any\n");                  \
        else                                                    \
  }
  
  #define ATTR_ADDR_MATCH(param)                                        \
-       {                                                       \
-               .attr = {                                       \
-                       .name = #param,                         \
-                       .mode = (S_IRUGO | S_IWUSR)             \
-               },                                              \
-               .show  = i7core_inject_show_##param,            \
-               .store = i7core_inject_store_##param,           \
-       }
+       static DEVICE_ATTR(param, S_IRUGO | S_IWUSR,            \
+                   i7core_inject_show_##param,                 \
+                   i7core_inject_store_##param)
  
  DECLARE_ADDR_MATCH(channel, 3);
  DECLARE_ADDR_MATCH(dimm, 3);
@@@ -854,14 -868,21 +868,21 @@@ DECLARE_ADDR_MATCH(bank, 32)
  DECLARE_ADDR_MATCH(page, 0x10000);
  DECLARE_ADDR_MATCH(col, 0x4000);
  
+ ATTR_ADDR_MATCH(channel);
+ ATTR_ADDR_MATCH(dimm);
+ ATTR_ADDR_MATCH(rank);
+ ATTR_ADDR_MATCH(bank);
+ ATTR_ADDR_MATCH(page);
+ ATTR_ADDR_MATCH(col);
  static int write_and_test(struct pci_dev *dev, const int where, const u32 val)
  {
        u32 read;
        int count;
  
-       debugf0("setting pci %02x:%02x.%x reg=%02x value=%08x\n",
-               dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
-               where, val);
+       edac_dbg(0, "setting pci %02x:%02x.%x reg=%02x value=%08x\n",
+                dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
+                where, val);
  
        for (count = 0; count < 10; count++) {
                if (count)
   *    is reliable enough to check if the MC is using the
   *    three channels. However, this is not clear at the datasheet.
   */
- static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
-                                      const char *data, size_t count)
+ static ssize_t i7core_inject_enable_store(struct device *dev,
+                                         struct device_attribute *mattr,
+                                         const char *data, size_t count)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct i7core_pvt *pvt = mci->pvt_info;
        u32 injectmask;
        u64 mask = 0;
        pci_write_config_dword(pvt->pci_noncore,
                               MC_CFG_CONTROL, 8);
  
-       debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
-               " inject 0x%08x\n",
-               mask, pvt->inject.eccmask, injectmask);
+       edac_dbg(0, "Error inject addr match 0x%016llx, ecc 0x%08x, inject 0x%08x\n",
+                mask, pvt->inject.eccmask, injectmask);
  
  
        return count;
  }
  
- static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci,
-                                       char *data)
+ static ssize_t i7core_inject_enable_show(struct device *dev,
+                                        struct device_attribute *mattr,
+                                        char *data)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct i7core_pvt *pvt = mci->pvt_info;
        u32 injectmask;
  
        pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
                               MC_CHANNEL_ERROR_INJECT, &injectmask);
  
-       debugf0("Inject error read: 0x%018x\n", injectmask);
+       edac_dbg(0, "Inject error read: 0x%018x\n", injectmask);
  
        if (injectmask & 0x0c)
                pvt->inject.enable = 1;
  
  #define DECLARE_COUNTER(param)                                        \
  static ssize_t i7core_show_counter_##param(                   \
-               struct mem_ctl_info *mci,                       \
-               char *data)                                     \
+       struct device *dev,                                     \
+       struct device_attribute *mattr,                         \
+       char *data)                                             \
  {                                                             \
+       struct mem_ctl_info *mci = to_mci(dev);                 \
        struct i7core_pvt *pvt = mci->pvt_info;                 \
                                                                \
-       debugf1("%s() \n", __func__);                           \
+       edac_dbg(1, "\n");                                      \
        if (!pvt->ce_count_available || (pvt->is_registered))   \
                return sprintf(data, "data unavailable\n");     \
        return sprintf(data, "%lu\n",                           \
  }
  
  #define ATTR_COUNTER(param)                                   \
-       {                                                       \
-               .attr = {                                       \
-                       .name = __stringify(udimm##param),      \
-                       .mode = (S_IRUGO | S_IWUSR)             \
-               },                                              \
-               .show  = i7core_show_counter_##param            \
-       }
+       static DEVICE_ATTR(udimm##param, S_IRUGO | S_IWUSR,     \
+                   i7core_show_counter_##param,                \
+                   NULL)
  
  DECLARE_COUNTER(0);
  DECLARE_COUNTER(1);
  DECLARE_COUNTER(2);
  
+ ATTR_COUNTER(0);
+ ATTR_COUNTER(1);
+ ATTR_COUNTER(2);
  /*
-  * Sysfs struct
+  * inject_addrmatch device sysfs struct
   */
  
- static const struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = {
-       ATTR_ADDR_MATCH(channel),
-       ATTR_ADDR_MATCH(dimm),
-       ATTR_ADDR_MATCH(rank),
-       ATTR_ADDR_MATCH(bank),
-       ATTR_ADDR_MATCH(page),
-       ATTR_ADDR_MATCH(col),
-       { } /* End of list */
+ static struct attribute *i7core_addrmatch_attrs[] = {
+       &dev_attr_channel.attr,
+       &dev_attr_dimm.attr,
+       &dev_attr_rank.attr,
+       &dev_attr_bank.attr,
+       &dev_attr_page.attr,
+       &dev_attr_col.attr,
+       NULL
  };
  
- static const struct mcidev_sysfs_group i7core_inject_addrmatch = {
-       .name  = "inject_addrmatch",
-       .mcidev_attr = i7core_addrmatch_attrs,
+ static struct attribute_group addrmatch_grp = {
+       .attrs  = i7core_addrmatch_attrs,
  };
  
- static const struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = {
-       ATTR_COUNTER(0),
-       ATTR_COUNTER(1),
-       ATTR_COUNTER(2),
-       { .attr = { .name = NULL } }
+ static const struct attribute_group *addrmatch_groups[] = {
+       &addrmatch_grp,
+       NULL
  };
  
- static const struct mcidev_sysfs_group i7core_udimm_counters = {
-       .name  = "all_channel_counts",
-       .mcidev_attr = i7core_udimm_counters_attrs,
+ static void addrmatch_release(struct device *device)
+ {
+       edac_dbg(1, "Releasing device %s\n", dev_name(device));
+       kfree(device);
+ }
+ static struct device_type addrmatch_type = {
+       .groups         = addrmatch_groups,
+       .release        = addrmatch_release,
  };
  
- static const struct mcidev_sysfs_attribute i7core_sysfs_rdimm_attrs[] = {
-       {
-               .attr = {
-                       .name = "inject_section",
-                       .mode = (S_IRUGO | S_IWUSR)
-               },
-               .show  = i7core_inject_section_show,
-               .store = i7core_inject_section_store,
-       }, {
-               .attr = {
-                       .name = "inject_type",
-                       .mode = (S_IRUGO | S_IWUSR)
-               },
-               .show  = i7core_inject_type_show,
-               .store = i7core_inject_type_store,
-       }, {
-               .attr = {
-                       .name = "inject_eccmask",
-                       .mode = (S_IRUGO | S_IWUSR)
-               },
-               .show  = i7core_inject_eccmask_show,
-               .store = i7core_inject_eccmask_store,
-       }, {
-               .grp = &i7core_inject_addrmatch,
-       }, {
-               .attr = {
-                       .name = "inject_enable",
-                       .mode = (S_IRUGO | S_IWUSR)
-               },
-               .show  = i7core_inject_enable_show,
-               .store = i7core_inject_enable_store,
-       },
-       { }     /* End of list */
+ /*
+  * all_channel_counts sysfs struct
+  */
+ static struct attribute *i7core_udimm_counters_attrs[] = {
+       &dev_attr_udimm0.attr,
+       &dev_attr_udimm1.attr,
+       &dev_attr_udimm2.attr,
+       NULL
  };
  
- static const struct mcidev_sysfs_attribute i7core_sysfs_udimm_attrs[] = {
-       {
-               .attr = {
-                       .name = "inject_section",
-                       .mode = (S_IRUGO | S_IWUSR)
-               },
-               .show  = i7core_inject_section_show,
-               .store = i7core_inject_section_store,
-       }, {
-               .attr = {
-                       .name = "inject_type",
-                       .mode = (S_IRUGO | S_IWUSR)
-               },
-               .show  = i7core_inject_type_show,
-               .store = i7core_inject_type_store,
-       }, {
-               .attr = {
-                       .name = "inject_eccmask",
-                       .mode = (S_IRUGO | S_IWUSR)
-               },
-               .show  = i7core_inject_eccmask_show,
-               .store = i7core_inject_eccmask_store,
-       }, {
-               .grp = &i7core_inject_addrmatch,
-       }, {
-               .attr = {
-                       .name = "inject_enable",
-                       .mode = (S_IRUGO | S_IWUSR)
-               },
-               .show  = i7core_inject_enable_show,
-               .store = i7core_inject_enable_store,
-       }, {
-               .grp = &i7core_udimm_counters,
-       },
-       { }     /* End of list */
+ static struct attribute_group all_channel_counts_grp = {
+       .attrs  = i7core_udimm_counters_attrs,
  };
  
+ static const struct attribute_group *all_channel_counts_groups[] = {
+       &all_channel_counts_grp,
+       NULL
+ };
+ static void all_channel_counts_release(struct device *device)
+ {
+       edac_dbg(1, "Releasing device %s\n", dev_name(device));
+       kfree(device);
+ }
+ static struct device_type all_channel_counts_type = {
+       .groups         = all_channel_counts_groups,
+       .release        = all_channel_counts_release,
+ };
+ /*
+  * inject sysfs attributes
+  */
+ static DEVICE_ATTR(inject_section, S_IRUGO | S_IWUSR,
+                  i7core_inject_section_show, i7core_inject_section_store);
+ static DEVICE_ATTR(inject_type, S_IRUGO | S_IWUSR,
+                  i7core_inject_type_show, i7core_inject_type_store);
+ static DEVICE_ATTR(inject_eccmask, S_IRUGO | S_IWUSR,
+                  i7core_inject_eccmask_show, i7core_inject_eccmask_store);
+ static DEVICE_ATTR(inject_enable, S_IRUGO | S_IWUSR,
+                  i7core_inject_enable_show, i7core_inject_enable_store);
+ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
+ {
+       struct i7core_pvt *pvt = mci->pvt_info;
+       int rc;
+       rc = device_create_file(&mci->dev, &dev_attr_inject_section);
+       if (rc < 0)
+               return rc;
+       rc = device_create_file(&mci->dev, &dev_attr_inject_type);
+       if (rc < 0)
+               return rc;
+       rc = device_create_file(&mci->dev, &dev_attr_inject_eccmask);
+       if (rc < 0)
+               return rc;
+       rc = device_create_file(&mci->dev, &dev_attr_inject_enable);
+       if (rc < 0)
+               return rc;
+       pvt->addrmatch_dev = kzalloc(sizeof(*pvt->addrmatch_dev), GFP_KERNEL);
+       if (!pvt->addrmatch_dev)
+               return rc;
+       pvt->addrmatch_dev->type = &addrmatch_type;
+       pvt->addrmatch_dev->bus = mci->dev.bus;
+       device_initialize(pvt->addrmatch_dev);
+       pvt->addrmatch_dev->parent = &mci->dev;
+       dev_set_name(pvt->addrmatch_dev, "inject_addrmatch");
+       dev_set_drvdata(pvt->addrmatch_dev, mci);
+       edac_dbg(1, "creating %s\n", dev_name(pvt->addrmatch_dev));
+       rc = device_add(pvt->addrmatch_dev);
+       if (rc < 0)
+               return rc;
+       if (!pvt->is_registered) {
+               pvt->chancounts_dev = kzalloc(sizeof(*pvt->chancounts_dev),
+                                             GFP_KERNEL);
+               if (!pvt->chancounts_dev) {
+                       put_device(pvt->addrmatch_dev);
+                       device_del(pvt->addrmatch_dev);
+                       return rc;
+               }
+               pvt->chancounts_dev->type = &all_channel_counts_type;
+               pvt->chancounts_dev->bus = mci->dev.bus;
+               device_initialize(pvt->chancounts_dev);
+               pvt->chancounts_dev->parent = &mci->dev;
+               dev_set_name(pvt->chancounts_dev, "all_channel_counts");
+               dev_set_drvdata(pvt->chancounts_dev, mci);
+               edac_dbg(1, "creating %s\n", dev_name(pvt->chancounts_dev));
+               rc = device_add(pvt->chancounts_dev);
+               if (rc < 0)
+                       return rc;
+       }
+       return 0;
+ }
+ static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
+ {
+       struct i7core_pvt *pvt = mci->pvt_info;
+       edac_dbg(1, "\n");
+       device_remove_file(&mci->dev, &dev_attr_inject_section);
+       device_remove_file(&mci->dev, &dev_attr_inject_type);
+       device_remove_file(&mci->dev, &dev_attr_inject_eccmask);
+       device_remove_file(&mci->dev, &dev_attr_inject_enable);
+       if (!pvt->is_registered) {
+               put_device(pvt->chancounts_dev);
+               device_del(pvt->chancounts_dev);
+       }
+       put_device(pvt->addrmatch_dev);
+       device_del(pvt->addrmatch_dev);
+ }
  /****************************************************************************
        Device initialization routines: put/get, init/exit
   ****************************************************************************/
@@@ -1164,14 -1248,14 +1248,14 @@@ static void i7core_put_devices(struct i
  {
        int i;
  
-       debugf0(__FILE__ ": %s()\n", __func__);
+       edac_dbg(0, "\n");
        for (i = 0; i < i7core_dev->n_devs; i++) {
                struct pci_dev *pdev = i7core_dev->pdev[i];
                if (!pdev)
                        continue;
-               debugf0("Removing dev %02x:%02x.%d\n",
-                       pdev->bus->number,
-                       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+               edac_dbg(0, "Removing dev %02x:%02x.%d\n",
+                        pdev->bus->number,
+                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
                pci_dev_put(pdev);
        }
  }
@@@ -1214,12 -1298,12 +1298,12 @@@ static unsigned i7core_pci_lastbus(void
  
        while ((b = pci_find_next_bus(b)) != NULL) {
                bus = b->number;
-               debugf0("Found bus %d\n", bus);
+               edac_dbg(0, "Found bus %d\n", bus);
                if (bus > last_bus)
                        last_bus = bus;
        }
  
-       debugf0("Last bus %d\n", last_bus);
+       edac_dbg(0, "Last bus %d\n", last_bus);
  
        return last_bus;
  }
@@@ -1246,7 -1330,7 +1330,7 @@@ static int i7core_get_onedevice(struct 
                              dev_descr->dev_id, *prev);
  
        /*
 -       * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs
 +       * On Xeon 55xx, the Intel QuickPath Arch Generic Non-core regs
         * is at addr 8086:2c40, instead of 8086:2c41. So, we need
         * to probe for the alternate address in case of failure
         */
                return -ENODEV;
        }
  
-       debugf0("Detected socket %d dev %02x:%02x.%d PCI ID %04x:%04x\n",
-               socket, bus, dev_descr->dev,
-               dev_descr->func,
-               PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
+       edac_dbg(0, "Detected socket %d dev %02x:%02x.%d PCI ID %04x:%04x\n",
+                socket, bus, dev_descr->dev,
+                dev_descr->func,
+                PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
  
        /*
         * As stated on drivers/pci/search.c, the reference count for
@@@ -1427,13 -1511,13 +1511,13 @@@ static int mci_bind_devs(struct mem_ctl
                                family = "unknown";
                                pvt->enable_scrub = false;
                        }
-                       debugf0("Detected a processor type %s\n", family);
+                       edac_dbg(0, "Detected a processor type %s\n", family);
                } else
                        goto error;
  
-               debugf0("Associated fn %d.%d, dev = %p, socket %d\n",
-                       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
-                       pdev, i7core_dev->socket);
+               edac_dbg(0, "Associated fn %d.%d, dev = %p, socket %d\n",
+                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+                        pdev, i7core_dev->socket);
  
                if (PCI_SLOT(pdev->devfn) == 3 &&
                        PCI_FUNC(pdev->devfn) == 2)
@@@ -1452,18 -1536,6 +1536,6 @@@ error
  /****************************************************************************
                        Error check routines
   ****************************************************************************/
- static void i7core_rdimm_update_errcount(struct mem_ctl_info *mci,
-                                     const int chan,
-                                     const int dimm,
-                                     const int add)
- {
-       int i;
-       for (i = 0; i < add; i++) {
-               edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 0, 0, 0,
-                                    chan, dimm, -1, "error", "", NULL);
-       }
- }
  
  static void i7core_rdimm_update_ce_count(struct mem_ctl_info *mci,
                                         const int chan,
  
        /*updated the edac core */
        if (add0 != 0)
-               i7core_rdimm_update_errcount(mci, chan, 0, add0);
+               edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, add0,
+                                    0, 0, 0,
+                                    chan, 0, -1, "error", "");
        if (add1 != 0)
-               i7core_rdimm_update_errcount(mci, chan, 1, add1);
+               edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, add1,
+                                    0, 0, 0,
+                                    chan, 1, -1, "error", "");
        if (add2 != 0)
-               i7core_rdimm_update_errcount(mci, chan, 2, add2);
+               edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, add2,
+                                    0, 0, 0,
+                                    chan, 2, -1, "error", "");
  }
  
  static void i7core_rdimm_check_mc_ecc_err(struct mem_ctl_info *mci)
        pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_5,
                                                                &rcv[2][1]);
        for (i = 0 ; i < 3; i++) {
-               debugf3("MC_COR_ECC_CNT%d = 0x%x; MC_COR_ECC_CNT%d = 0x%x\n",
-                       (i * 2), rcv[i][0], (i * 2) + 1, rcv[i][1]);
+               edac_dbg(3, "MC_COR_ECC_CNT%d = 0x%x; MC_COR_ECC_CNT%d = 0x%x\n",
+                        (i * 2), rcv[i][0], (i * 2) + 1, rcv[i][1]);
                /*if the channel has 3 dimms*/
                if (pvt->channel[i].dimms > 2) {
                        new0 = DIMM_BOT_COR_ERR(rcv[i][0]);
@@@ -1562,7 -1639,7 +1639,7 @@@ static void i7core_udimm_check_mc_ecc_e
        int new0, new1, new2;
  
        if (!pvt->pci_mcr[4]) {
-               debugf0("%s MCR registers not found\n", __func__);
+               edac_dbg(0, "MCR registers not found\n");
                return;
        }
  
@@@ -1626,7 -1703,7 +1703,7 @@@ static void i7core_mce_output_error(str
                                    const struct mce *m)
  {
        struct i7core_pvt *pvt = mci->pvt_info;
-       char *type, *optype, *err, msg[80];
+       char *type, *optype, *err;
        enum hw_event_mc_err_type tp_event;
        unsigned long error = m->status & 0x1ff0000l;
        bool uncorrected_error = m->mcgstatus & 1ll << 61;
                err = "unknown";
        }
  
-       snprintf(msg, sizeof(msg), "count=%d %s", core_err_cnt, optype);
        /*
         * Call the helper to output message
         * FIXME: what to do if core_err_cnt > 1? Currently, it generates
         * only one event
         */
        if (uncorrected_error || !pvt->is_registered)
-               edac_mc_handle_error(tp_event, mci,
+               edac_mc_handle_error(tp_event, mci, core_err_cnt,
                                     m->addr >> PAGE_SHIFT,
                                     m->addr & ~PAGE_MASK,
                                     syndrome,
                                     channel, dimm, -1,
-                                    err, msg, m);
+                                    err, optype);
  }
  
  /*
@@@ -1814,6 -1889,12 +1889,6 @@@ static int i7core_mce_check_error(struc
        if (mce->bank != 8)
                return NOTIFY_DONE;
  
 -#ifdef CONFIG_SMP
 -      /* Only handle if it is the right mc controller */
 -      if (mce->socketid != pvt->i7core_dev->socket)
 -              return NOTIFY_DONE;
 -#endif
 -
        smp_rmb();
        if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) {
                smp_wmb();
@@@ -2008,7 -2089,7 +2083,7 @@@ static int set_sdram_scrub_rate(struct 
  
  /*
   * get_sdram_scrub_rate               This routine convert current scrub rate value
 - *                            into byte/sec bandwidth accourding to
 + *                            into byte/sec bandwidth according to
   *                            SCRUBINTERVAL formula found in datasheet.
   */
  static int get_sdram_scrub_rate(struct mem_ctl_info *mci)
@@@ -2094,8 -2175,7 +2169,7 @@@ static void i7core_unregister_mci(struc
        struct i7core_pvt *pvt;
  
        if (unlikely(!mci || !mci->pvt_info)) {
-               debugf0("MC: " __FILE__ ": %s(): dev = %p\n",
-                       __func__, &i7core_dev->pdev[0]->dev);
+               edac_dbg(0, "MC: dev = %p\n", &i7core_dev->pdev[0]->dev);
  
                i7core_printk(KERN_ERR, "Couldn't find mci handler\n");
                return;
  
        pvt = mci->pvt_info;
  
-       debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
-               __func__, mci, &i7core_dev->pdev[0]->dev);
+       edac_dbg(0, "MC: mci = %p, dev = %p\n", mci, &i7core_dev->pdev[0]->dev);
  
        /* Disable scrubrate setting */
        if (pvt->enable_scrub)
                disable_sdram_scrub_setting(mci);
  
 -      mce_unregister_decode_chain(&i7_mce_dec);
 -
        /* Disable EDAC polling */
        i7core_pci_ctl_release(pvt);
  
        /* Remove MC sysfs nodes */
-       edac_mc_del_mc(mci->dev);
+       i7core_delete_sysfs_devices(mci);
+       edac_mc_del_mc(mci->pdev);
  
-       debugf1("%s: free mci struct\n", mci->ctl_name);
+       edac_dbg(1, "%s: free mci struct\n", mci->ctl_name);
        kfree(mci->ctl_name);
        edac_mc_free(mci);
        i7core_dev->mci = NULL;
@@@ -2142,8 -2224,7 +2216,7 @@@ static int i7core_register_mci(struct i
        if (unlikely(!mci))
                return -ENOMEM;
  
-       debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
-               __func__, mci, &i7core_dev->pdev[0]->dev);
+       edac_dbg(0, "MC: mci = %p, dev = %p\n", mci, &i7core_dev->pdev[0]->dev);
  
        pvt = mci->pvt_info;
        memset(pvt, 0, sizeof(*pvt));
        if (unlikely(rc < 0))
                goto fail0;
  
-       if (pvt->is_registered)
-               mci->mc_driver_sysfs_attributes = i7core_sysfs_rdimm_attrs;
-       else
-               mci->mc_driver_sysfs_attributes = i7core_sysfs_udimm_attrs;
  
        /* Get dimm basic config */
        get_dimm_config(mci);
        /* record ptr to the generic device */
-       mci->dev = &i7core_dev->pdev[0]->dev;
+       mci->pdev = &i7core_dev->pdev[0]->dev;
        /* Set the function pointer to an actual operation function */
        mci->edac_check = i7core_check_error;
  
  
        /* add this new MC control structure to EDAC's list of MCs */
        if (unlikely(edac_mc_add_mc(mci))) {
-               debugf0("MC: " __FILE__
-                       ": %s(): failed edac_mc_add_mc()\n", __func__);
+               edac_dbg(0, "MC: failed edac_mc_add_mc()\n");
                /* FIXME: perhaps some code should go here that disables error
                 * reporting if we just enabled it
                 */
                rc = -EINVAL;
                goto fail0;
        }
+       if (i7core_create_sysfs_devices(mci)) {
+               edac_dbg(0, "MC: failed to create sysfs nodes\n");
+               edac_mc_del_mc(mci->pdev);
+               rc = -EINVAL;
+               goto fail0;
+       }
  
        /* Default error mask is any memory */
        pvt->inject.channel = 0;
        /* DCLK for scrub rate setting */
        pvt->dclk_freq = get_dclk_freq();
  
 -      mce_register_decode_chain(&i7_mce_dec);
 -
        return 0;
  
  fail0:
@@@ -2298,7 -2382,7 +2372,7 @@@ static void __devexit i7core_remove(str
  {
        struct i7core_dev *i7core_dev;
  
-       debugf0(__FILE__ ": %s()\n", __func__);
+       edac_dbg(0, "\n");
  
        /*
         * we have a trouble here: pdev value for removal will be wrong, since
@@@ -2347,7 -2431,7 +2421,7 @@@ static int __init i7core_init(void
  {
        int pci_rc;
  
-       debugf2("MC: " __FILE__ ": %s()\n", __func__);
+       edac_dbg(2, "\n");
  
        /* Ensure that the OPSTATE is set correctly for POLL or NMI */
        opstate_init();
  
        pci_rc = pci_register_driver(&i7core_driver);
  
 -      if (pci_rc >= 0)
 +      if (pci_rc >= 0) {
 +              mce_register_decode_chain(&i7_mce_dec);
                return 0;
 +      }
  
        i7core_printk(KERN_ERR, "Failed to register device with error %d.\n",
                      pci_rc);
   */
  static void __exit i7core_exit(void)
  {
-       debugf2("MC: " __FILE__ ": %s()\n", __func__);
+       edac_dbg(2, "\n");
        pci_unregister_driver(&i7core_driver);
 +      mce_unregister_decode_chain(&i7_mce_dec);
  }
  
  module_init(i7core_init);
index 0e374625f6f894a20272df947ffe2f3b7620422f,117cf00bd7436c24ce22a67aede1802615a659e2..a1e791ec25d38514b7c47ae27bd2cab0198ded68
@@@ -49,34 -49,45 +49,45 @@@ static u32 orig_hid1[2]
  
  /************************ MC SYSFS parts ***********************************/
  
- static ssize_t mpc85xx_mc_inject_data_hi_show(struct mem_ctl_info *mci,
+ #define to_mci(k) container_of(k, struct mem_ctl_info, dev)
+ static ssize_t mpc85xx_mc_inject_data_hi_show(struct device *dev,
+                                             struct device_attribute *mattr,
                                              char *data)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
        return sprintf(data, "0x%08x",
                       in_be32(pdata->mc_vbase +
                               MPC85XX_MC_DATA_ERR_INJECT_HI));
  }
  
- static ssize_t mpc85xx_mc_inject_data_lo_show(struct mem_ctl_info *mci,
+ static ssize_t mpc85xx_mc_inject_data_lo_show(struct device *dev,
+                                             struct device_attribute *mattr,
                                              char *data)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
        return sprintf(data, "0x%08x",
                       in_be32(pdata->mc_vbase +
                               MPC85XX_MC_DATA_ERR_INJECT_LO));
  }
  
- static ssize_t mpc85xx_mc_inject_ctrl_show(struct mem_ctl_info *mci, char *data)
+ static ssize_t mpc85xx_mc_inject_ctrl_show(struct device *dev,
+                                          struct device_attribute *mattr,
+                                          char *data)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
        return sprintf(data, "0x%08x",
                       in_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT));
  }
  
- static ssize_t mpc85xx_mc_inject_data_hi_store(struct mem_ctl_info *mci,
+ static ssize_t mpc85xx_mc_inject_data_hi_store(struct device *dev,
+                                              struct device_attribute *mattr,
                                               const char *data, size_t count)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
        if (isdigit(*data)) {
                out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_HI,
        return 0;
  }
  
- static ssize_t mpc85xx_mc_inject_data_lo_store(struct mem_ctl_info *mci,
+ static ssize_t mpc85xx_mc_inject_data_lo_store(struct device *dev,
+                                              struct device_attribute *mattr,
                                               const char *data, size_t count)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
        if (isdigit(*data)) {
                out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_LO,
        return 0;
  }
  
- static ssize_t mpc85xx_mc_inject_ctrl_store(struct mem_ctl_info *mci,
-                                           const char *data, size_t count)
+ static ssize_t mpc85xx_mc_inject_ctrl_store(struct device *dev,
+                                              struct device_attribute *mattr,
+                                              const char *data, size_t count)
  {
+       struct mem_ctl_info *mci = to_mci(dev);
        struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
        if (isdigit(*data)) {
                out_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT,
        return 0;
  }
  
- static struct mcidev_sysfs_attribute mpc85xx_mc_sysfs_attributes[] = {
-       {
-        .attr = {
-                 .name = "inject_data_hi",
-                 .mode = (S_IRUGO | S_IWUSR)
-                 },
-        .show = mpc85xx_mc_inject_data_hi_show,
-        .store = mpc85xx_mc_inject_data_hi_store},
-       {
-        .attr = {
-                 .name = "inject_data_lo",
-                 .mode = (S_IRUGO | S_IWUSR)
-                 },
-        .show = mpc85xx_mc_inject_data_lo_show,
-        .store = mpc85xx_mc_inject_data_lo_store},
-       {
-        .attr = {
-                 .name = "inject_ctrl",
-                 .mode = (S_IRUGO | S_IWUSR)
-                 },
-        .show = mpc85xx_mc_inject_ctrl_show,
-        .store = mpc85xx_mc_inject_ctrl_store},
+ DEVICE_ATTR(inject_data_hi, S_IRUGO | S_IWUSR,
+           mpc85xx_mc_inject_data_hi_show, mpc85xx_mc_inject_data_hi_store);
+ DEVICE_ATTR(inject_data_lo, S_IRUGO | S_IWUSR,
+           mpc85xx_mc_inject_data_lo_show, mpc85xx_mc_inject_data_lo_store);
+ DEVICE_ATTR(inject_ctrl, S_IRUGO | S_IWUSR,
+           mpc85xx_mc_inject_ctrl_show, mpc85xx_mc_inject_ctrl_store);
  
-       /* End of list */
-       {
-        .attr = {.name = NULL}
-        }
- };
+ static int mpc85xx_create_sysfs_attributes(struct mem_ctl_info *mci)
+ {
+       int rc;
+       rc = device_create_file(&mci->dev, &dev_attr_inject_data_hi);
+       if (rc < 0)
+               return rc;
+       rc = device_create_file(&mci->dev, &dev_attr_inject_data_lo);
+       if (rc < 0)
+               return rc;
+       rc = device_create_file(&mci->dev, &dev_attr_inject_ctrl);
+       if (rc < 0)
+               return rc;
  
- static void mpc85xx_set_mc_sysfs_attributes(struct mem_ctl_info *mci)
+       return 0;
+ }
+ static void mpc85xx_remove_sysfs_attributes(struct mem_ctl_info *mci)
  {
-       mci->mc_driver_sysfs_attributes = mpc85xx_mc_sysfs_attributes;
+       device_remove_file(&mci->dev, &dev_attr_inject_data_hi);
+       device_remove_file(&mci->dev, &dev_attr_inject_data_lo);
+       device_remove_file(&mci->dev, &dev_attr_inject_ctrl);
  }
  
  /**************************** PCI Err device ***************************/
@@@ -268,7 -280,7 +280,7 @@@ static int __devinit mpc85xx_pci_err_pr
        out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0);
  
        if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
-               debugf3("%s(): failed edac_pci_add_device()\n", __func__);
+               edac_dbg(3, "failed edac_pci_add_device()\n");
                goto err;
        }
  
        }
  
        devres_remove_group(&op->dev, mpc85xx_pci_err_probe);
-       debugf3("%s(): success\n", __func__);
+       edac_dbg(3, "success\n");
        printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n");
  
        return 0;
@@@ -309,7 -321,7 +321,7 @@@ static int mpc85xx_pci_err_remove(struc
        struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev);
        struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
  
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
        out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR,
                 orig_pci_err_cap_dr);
@@@ -570,7 -582,7 +582,7 @@@ static int __devinit mpc85xx_l2_err_pro
        pdata->edac_idx = edac_dev_idx++;
  
        if (edac_device_add_device(edac_dev) > 0) {
-               debugf3("%s(): failed edac_device_add_device()\n", __func__);
+               edac_dbg(3, "failed edac_device_add_device()\n");
                goto err;
        }
  
  
        devres_remove_group(&op->dev, mpc85xx_l2_err_probe);
  
-       debugf3("%s(): success\n", __func__);
+       edac_dbg(3, "success\n");
        printk(KERN_INFO EDAC_MOD_STR " L2 err registered\n");
  
        return 0;
@@@ -616,7 -628,7 +628,7 @@@ static int mpc85xx_l2_err_remove(struc
        struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev);
        struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
  
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
        if (edac_op_state == EDAC_OPSTATE_INT) {
                out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, 0);
@@@ -813,7 -825,7 +825,7 @@@ static void mpc85xx_mc_check(struct mem
        pfn = err_addr >> PAGE_SHIFT;
  
        for (row_index = 0; row_index < mci->nr_csrows; row_index++) {
-               csrow = &mci->csrows[row_index];
+               csrow = mci->csrows[row_index];
                if ((pfn >= csrow->first_page) && (pfn <= csrow->last_page))
                        break;
        }
                mpc85xx_mc_printk(mci, KERN_ERR, "PFN out of range!\n");
  
        if (err_detect & DDR_EDE_SBE)
-               edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
+               edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
                                     pfn, err_addr & ~PAGE_MASK, syndrome,
                                     row_index, 0, -1,
-                                    mci->ctl_name, "", NULL);
+                                    mci->ctl_name, "");
  
        if (err_detect & DDR_EDE_MBE)
-               edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
+               edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
                                     pfn, err_addr & ~PAGE_MASK, syndrome,
                                     row_index, 0, -1,
-                                    mci->ctl_name, "", NULL);
+                                    mci->ctl_name, "");
  
        out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, err_detect);
  }
@@@ -933,8 -945,8 +945,8 @@@ static void __devinit mpc85xx_init_csro
                u32 start;
                u32 end;
  
-               csrow = &mci->csrows[index];
-               dimm = csrow->channels[0].dimm;
+               csrow = mci->csrows[index];
+               dimm = csrow->channels[0]->dimm;
  
                cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 +
                                  (index * MPC85XX_MC_CS_BNDS_OFS));
@@@ -980,8 -992,7 +992,8 @@@ static int __devinit mpc85xx_mc_err_pro
        layers[1].type = EDAC_MC_LAYER_CHANNEL;
        layers[1].size = 1;
        layers[1].is_virt_csrow = false;
 -      mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), sizeof(*pdata));
 +      mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers,
 +                          sizeof(*pdata));
        if (!mci) {
                devres_release_group(&op->dev, mpc85xx_mc_err_probe);
                return -ENOMEM;
        pdata = mci->pvt_info;
        pdata->name = "mpc85xx_mc_err";
        pdata->irq = NO_IRQ;
-       mci->dev = &op->dev;
+       mci->pdev = &op->dev;
        pdata->edac_idx = edac_mc_idx++;
-       dev_set_drvdata(mci->dev, mci);
+       dev_set_drvdata(mci->pdev, mci);
        mci->ctl_name = pdata->name;
        mci->dev_name = pdata->name;
  
                goto err;
        }
  
-       debugf3("%s(): init mci\n", __func__);
+       edac_dbg(3, "init mci\n");
        mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_RDDR2 |
            MEM_FLAG_DDR | MEM_FLAG_DDR2;
        mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
  
        mci->scrub_mode = SCRUB_SW_SRC;
  
-       mpc85xx_set_mc_sysfs_attributes(mci);
        mpc85xx_init_csrows(mci);
  
        /* store the original error disable bits */
        out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0);
  
        if (edac_mc_add_mc(mci)) {
-               debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
+               edac_dbg(3, "failed edac_mc_add_mc()\n");
+               goto err;
+       }
+       if (mpc85xx_create_sysfs_attributes(mci)) {
+               edac_mc_del_mc(mci->pdev);
+               edac_dbg(3, "failed edac_mc_add_mc()\n");
                goto err;
        }
  
        }
  
        devres_remove_group(&op->dev, mpc85xx_mc_err_probe);
-       debugf3("%s(): success\n", __func__);
+       edac_dbg(3, "success\n");
        printk(KERN_INFO EDAC_MOD_STR " MC err registered\n");
  
        return 0;
@@@ -1106,7 -1121,7 +1122,7 @@@ static int mpc85xx_mc_err_remove(struc
        struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
        struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
  
-       debugf0("%s()\n", __func__);
+       edac_dbg(0, "\n");
  
        if (edac_op_state == EDAC_OPSTATE_INT) {
                out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_INT_EN, 0);
                 orig_ddr_err_disable);
        out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, orig_ddr_err_sbe);
  
+       mpc85xx_remove_sysfs_attributes(mci);
        edac_mc_del_mc(&op->dev);
        edac_mc_free(mci);
        return 0;
diff --combined drivers/edac/sb_edac.c
index 36ad17e79d6183e3f21bf63f3266dc169f3941a0,6f8861369e7dffbb8b6401a20e0a7f97de2c5c8b..f3b1f9fafa4b20b4f40917bcbab827ad760515df
@@@ -58,7 -58,7 +58,7 @@@ static int probed
  
  /*
   * FIXME: For now, let's order by device function, as it makes
 - * easier for driver's development proccess. This table should be
 + * easier for driver's development process. This table should be
   * moved to pci_id.h when submitted upstream
   */
  #define PCI_DEVICE_ID_INTEL_SBRIDGE_SAD0      0x3cf4  /* 12.6 */
@@@ -373,7 -373,7 +373,7 @@@ static DEFINE_PCI_DEVICE_TABLE(sbridge_
  
  
  /****************************************************************************
 -                      Anciliary status routines
 +                      Ancillary status routines
   ****************************************************************************/
  
  static inline int numrank(u32 mtr)
        int ranks = (1 << RANK_CNT_BITS(mtr));
  
        if (ranks > 4) {
-               debugf0("Invalid number of ranks: %d (max = 4) raw value = %x (%04x)",
-                       ranks, (unsigned int)RANK_CNT_BITS(mtr), mtr);
+               edac_dbg(0, "Invalid number of ranks: %d (max = 4) raw value = %x (%04x)\n",
+                        ranks, (unsigned int)RANK_CNT_BITS(mtr), mtr);
                return -EINVAL;
        }
  
@@@ -394,8 -394,8 +394,8 @@@ static inline int numrow(u32 mtr
        int rows = (RANK_WIDTH_BITS(mtr) + 12);
  
        if (rows < 13 || rows > 18) {
-               debugf0("Invalid number of rows: %d (should be between 14 and 17) raw value = %x (%04x)",
-                       rows, (unsigned int)RANK_WIDTH_BITS(mtr), mtr);
+               edac_dbg(0, "Invalid number of rows: %d (should be between 14 and 17) raw value = %x (%04x)\n",
+                        rows, (unsigned int)RANK_WIDTH_BITS(mtr), mtr);
                return -EINVAL;
        }
  
@@@ -407,8 -407,8 +407,8 @@@ static inline int numcol(u32 mtr
        int cols = (COL_WIDTH_BITS(mtr) + 10);
  
        if (cols > 12) {
-               debugf0("Invalid number of cols: %d (max = 4) raw value = %x (%04x)",
-                       cols, (unsigned int)COL_WIDTH_BITS(mtr), mtr);
+               edac_dbg(0, "Invalid number of cols: %d (max = 4) raw value = %x (%04x)\n",
+                        cols, (unsigned int)COL_WIDTH_BITS(mtr), mtr);
                return -EINVAL;
        }
  
@@@ -475,8 -475,8 +475,8 @@@ static struct pci_dev *get_pdev_slot_fu
  
                if (PCI_SLOT(sbridge_dev->pdev[i]->devfn) == slot &&
                    PCI_FUNC(sbridge_dev->pdev[i]->devfn) == func) {
-                       debugf1("Associated %02x.%02x.%d with %p\n",
-                               bus, slot, func, sbridge_dev->pdev[i]);
+                       edac_dbg(1, "Associated %02x.%02x.%d with %p\n",
+                                bus, slot, func, sbridge_dev->pdev[i]);
                        return sbridge_dev->pdev[i];
                }
        }
@@@ -523,45 -523,45 +523,45 @@@ static int get_dimm_config(struct mem_c
  
        pci_read_config_dword(pvt->pci_br, SAD_CONTROL, &reg);
        pvt->sbridge_dev->node_id = NODE_ID(reg);
-       debugf0("mc#%d: Node ID: %d, source ID: %d\n",
-               pvt->sbridge_dev->mc,
-               pvt->sbridge_dev->node_id,
-               pvt->sbridge_dev->source_id);
+       edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n",
+                pvt->sbridge_dev->mc,
+                pvt->sbridge_dev->node_id,
+                pvt->sbridge_dev->source_id);
  
        pci_read_config_dword(pvt->pci_ras, RASENABLES, &reg);
        if (IS_MIRROR_ENABLED(reg)) {
-               debugf0("Memory mirror is enabled\n");
+               edac_dbg(0, "Memory mirror is enabled\n");
                pvt->is_mirrored = true;
        } else {
-               debugf0("Memory mirror is disabled\n");
+               edac_dbg(0, "Memory mirror is disabled\n");
                pvt->is_mirrored = false;
        }
  
        pci_read_config_dword(pvt->pci_ta, MCMTR, &pvt->info.mcmtr);
        if (IS_LOCKSTEP_ENABLED(pvt->info.mcmtr)) {
-               debugf0("Lockstep is enabled\n");
+               edac_dbg(0, "Lockstep is enabled\n");
                mode = EDAC_S8ECD8ED;
                pvt->is_lockstep = true;
        } else {
-               debugf0("Lockstep is disabled\n");
+               edac_dbg(0, "Lockstep is disabled\n");
                mode = EDAC_S4ECD4ED;
                pvt->is_lockstep = false;
        }
        if (IS_CLOSE_PG(pvt->info.mcmtr)) {
-               debugf0("address map is on closed page mode\n");
+               edac_dbg(0, "address map is on closed page mode\n");
                pvt->is_close_pg = true;
        } else {
-               debugf0("address map is on open page mode\n");
+               edac_dbg(0, "address map is on open page mode\n");
                pvt->is_close_pg = false;
        }
  
 -      pci_read_config_dword(pvt->pci_ta, RANK_CFG_A, &reg);
 +      pci_read_config_dword(pvt->pci_ddrio, RANK_CFG_A, &reg);
        if (IS_RDIMM_ENABLED(reg)) {
                /* FIXME: Can also be LRDIMM */
-               debugf0("Memory is registered\n");
+               edac_dbg(0, "Memory is registered\n");
                mtype = MEM_RDDR3;
        } else {
-               debugf0("Memory is unregistered\n");
+               edac_dbg(0, "Memory is unregistered\n");
                mtype = MEM_DDR3;
        }
  
                                       i, j, 0);
                        pci_read_config_dword(pvt->pci_tad[i],
                                              mtr_regs[j], &mtr);
-                       debugf4("Channel #%d  MTR%d = %x\n", i, j, mtr);
+                       edac_dbg(4, "Channel #%d  MTR%d = %x\n", i, j, mtr);
                        if (IS_DIMM_PRESENT(mtr)) {
                                pvt->channel[i].dimms++;
  
                                size = (rows * cols * banks * ranks) >> (20 - 3);
                                npages = MiB_TO_PAGES(size);
  
-                               debugf0("mc#%d: channel %d, dimm %d, %d Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
-                                       pvt->sbridge_dev->mc, i, j,
-                                       size, npages,
-                                       banks, ranks, rows, cols);
+                               edac_dbg(0, "mc#%d: channel %d, dimm %d, %d Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
+                                        pvt->sbridge_dev->mc, i, j,
+                                        size, npages,
+                                        banks, ranks, rows, cols);
  
                                dimm->nr_pages = npages;
                                dimm->grain = 32;
@@@ -629,8 -629,7 +629,7 @@@ static void get_memory_layout(const str
        tmp_mb = (1 + pvt->tolm) >> 20;
  
        mb = div_u64_rem(tmp_mb, 1000, &kb);
-       debugf0("TOLM: %u.%03u GB (0x%016Lx)\n",
-               mb, kb, (u64)pvt->tolm);
+       edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tolm);
  
        /* Address range is already 45:25 */
        pci_read_config_dword(pvt->pci_sad1, TOHM,
        tmp_mb = (1 + pvt->tohm) >> 20;
  
        mb = div_u64_rem(tmp_mb, 1000, &kb);
-       debugf0("TOHM: %u.%03u GB (0x%016Lx)",
-               mb, kb, (u64)pvt->tohm);
+       edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)", mb, kb, (u64)pvt->tohm);
  
        /*
         * Step 2) Get SAD range and SAD Interleave list
  
                tmp_mb = (limit + 1) >> 20;
                mb = div_u64_rem(tmp_mb, 1000, &kb);
-               debugf0("SAD#%d %s up to %u.%03u GB (0x%016Lx) %s reg=0x%08x\n",
-                       n_sads,
-                       get_dram_attr(reg),
-                       mb, kb,
-                       ((u64)tmp_mb) << 20L,
-                       INTERLEAVE_MODE(reg) ? "Interleave: 8:6" : "Interleave: [8:6]XOR[18:16]",
-                       reg);
+               edac_dbg(0, "SAD#%d %s up to %u.%03u GB (0x%016Lx) Interleave: %s reg=0x%08x\n",
+                        n_sads,
+                        get_dram_attr(reg),
+                        mb, kb,
+                        ((u64)tmp_mb) << 20L,
+                        INTERLEAVE_MODE(reg) ? "8:6" : "[8:6]XOR[18:16]",
+                        reg);
                prv = limit;
  
                pci_read_config_dword(pvt->pci_sad0, interleave_list[n_sads],
                        if (j > 0 && sad_interl == sad_pkg(reg, j))
                                break;
  
-                       debugf0("SAD#%d, interleave #%d: %d\n",
-                       n_sads, j, sad_pkg(reg, j));
+                       edac_dbg(0, "SAD#%d, interleave #%d: %d\n",
+                                n_sads, j, sad_pkg(reg, j));
                }
        }
  
                tmp_mb = (limit + 1) >> 20;
  
                mb = div_u64_rem(tmp_mb, 1000, &kb);
-               debugf0("TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n",
-                       n_tads, mb, kb,
-                       ((u64)tmp_mb) << 20L,
-                       (u32)TAD_SOCK(reg),
-                       (u32)TAD_CH(reg),
-                       (u32)TAD_TGT0(reg),
-                       (u32)TAD_TGT1(reg),
-                       (u32)TAD_TGT2(reg),
-                       (u32)TAD_TGT3(reg),
-                       reg);
+               edac_dbg(0, "TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n",
+                        n_tads, mb, kb,
+                        ((u64)tmp_mb) << 20L,
+                        (u32)TAD_SOCK(reg),
+                        (u32)TAD_CH(reg),
+                        (u32)TAD_TGT0(reg),
+                        (u32)TAD_TGT1(reg),
+                        (u32)TAD_TGT2(reg),
+                        (u32)TAD_TGT3(reg),
+                        reg);
                prv = limit;
        }
  
                                              &reg);
                        tmp_mb = TAD_OFFSET(reg) >> 20;
                        mb = div_u64_rem(tmp_mb, 1000, &kb);
-                       debugf0("TAD CH#%d, offset #%d: %u.%03u GB (0x%016Lx), reg=0x%08x\n",
-                               i, j,
-                               mb, kb,
-                               ((u64)tmp_mb) << 20L,
-                               reg);
+                       edac_dbg(0, "TAD CH#%d, offset #%d: %u.%03u GB (0x%016Lx), reg=0x%08x\n",
+                                i, j,
+                                mb, kb,
+                                ((u64)tmp_mb) << 20L,
+                                reg);
                }
        }
  
                        tmp_mb = RIR_LIMIT(reg) >> 20;
                        rir_way = 1 << RIR_WAY(reg);
                        mb = div_u64_rem(tmp_mb, 1000, &kb);
-                       debugf0("CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n",
-                               i, j,
-                               mb, kb,
-                               ((u64)tmp_mb) << 20L,
-                               rir_way,
-                               reg);
+                       edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n",
+                                i, j,
+                                mb, kb,
+                                ((u64)tmp_mb) << 20L,
+                                rir_way,
+                                reg);
  
                        for (k = 0; k < rir_way; k++) {
                                pci_read_config_dword(pvt->pci_tad[i],
                                tmp_mb = RIR_OFFSET(reg) << 6;
  
                                mb = div_u64_rem(tmp_mb, 1000, &kb);
-                               debugf0("CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
-                                       i, j, k,
-                                       mb, kb,
-                                       ((u64)tmp_mb) << 20L,
-                                       (u32)RIR_RNK_TGT(reg),
-                                       reg);
+                               edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
+                                        i, j, k,
+                                        mb, kb,
+                                        ((u64)tmp_mb) << 20L,
+                                        (u32)RIR_RNK_TGT(reg),
+                                        reg);
                        }
                }
        }
@@@ -853,16 -851,16 +851,16 @@@ static int get_memory_error_data(struc
                if (sad_way > 0 && sad_interl == sad_pkg(reg, sad_way))
                        break;
                sad_interleave[sad_way] = sad_pkg(reg, sad_way);
-               debugf0("SAD interleave #%d: %d\n",
-                       sad_way, sad_interleave[sad_way]);
+               edac_dbg(0, "SAD interleave #%d: %d\n",
+                        sad_way, sad_interleave[sad_way]);
        }
-       debugf0("mc#%d: Error detected on SAD#%d: address 0x%016Lx < 0x%016Lx, Interleave [%d:6]%s\n",
-               pvt->sbridge_dev->mc,
-               n_sads,
-               addr,
-               limit,
-               sad_way + 7,
-               interleave_mode ? "" : "XOR[18:16]");
+       edac_dbg(0, "mc#%d: Error detected on SAD#%d: address 0x%016Lx < 0x%016Lx, Interleave [%d:6]%s\n",
+                pvt->sbridge_dev->mc,
+                n_sads,
+                addr,
+                limit,
+                sad_way + 7,
+                interleave_mode ? "" : "XOR[18:16]");
        if (interleave_mode)
                idx = ((addr >> 6) ^ (addr >> 16)) & 7;
        else
                return -EINVAL;
        }
        *socket = sad_interleave[idx];
-       debugf0("SAD interleave index: %d (wayness %d) = CPU socket %d\n",
-               idx, sad_way, *socket);
+       edac_dbg(0, "SAD interleave index: %d (wayness %d) = CPU socket %d\n",
+                idx, sad_way, *socket);
  
        /*
         * Move to the proper node structure, in order to access the
  
        offset = TAD_OFFSET(tad_offset);
  
-       debugf0("TAD#%d: address 0x%016Lx < 0x%016Lx, socket interleave %d, channel interleave %d (offset 0x%08Lx), index %d, base ch: %d, ch mask: 0x%02lx\n",
-               n_tads,
-               addr,
-               limit,
-               (u32)TAD_SOCK(reg),
-               ch_way,
-               offset,
-               idx,
-               base_ch,
-               *channel_mask);
+       edac_dbg(0, "TAD#%d: address 0x%016Lx < 0x%016Lx, socket interleave %d, channel interleave %d (offset 0x%08Lx), index %d, base ch: %d, ch mask: 0x%02lx\n",
+                n_tads,
+                addr,
+                limit,
+                (u32)TAD_SOCK(reg),
+                ch_way,
+                offset,
+                idx,
+                base_ch,
+                *channel_mask);
  
        /* Calculate channel address */
        /* Remove the TAD offset */
  
                limit = RIR_LIMIT(reg);
                mb = div_u64_rem(limit >> 20, 1000, &kb);
-               debugf0("RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n",
-                       n_rir,
-                       mb, kb,
-                       limit,
-                       1 << RIR_WAY(reg));
+               edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n",
+                        n_rir,
+                        mb, kb,
+                        limit,
+                        1 << RIR_WAY(reg));
                if  (ch_addr <= limit)
                        break;
        }
                              &reg);
        *rank = RIR_RNK_TGT(reg);
  
-       debugf0("RIR#%d: channel address 0x%08Lx < 0x%08Lx, RIR interleave %d, index %d\n",
-               n_rir,
-               ch_addr,
-               limit,
-               rir_way,
-               idx);
+       edac_dbg(0, "RIR#%d: channel address 0x%08Lx < 0x%08Lx, RIR interleave %d, index %d\n",
+                n_rir,
+                ch_addr,
+                limit,
+                rir_way,
+                idx);
  
        return 0;
  }
@@@ -1064,14 -1062,14 +1062,14 @@@ static void sbridge_put_devices(struct 
  {
        int i;
  
-       debugf0(__FILE__ ": %s()\n", __func__);
+       edac_dbg(0, "\n");
        for (i = 0; i < sbridge_dev->n_devs; i++) {
                struct pci_dev *pdev = sbridge_dev->pdev[i];
                if (!pdev)
                        continue;
-               debugf0("Removing dev %02x:%02x.%d\n",
-                       pdev->bus->number,
-                       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+               edac_dbg(0, "Removing dev %02x:%02x.%d\n",
+                        pdev->bus->number,
+                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
                pci_dev_put(pdev);
        }
  }
@@@ -1177,10 -1175,9 +1175,9 @@@ static int sbridge_get_onedevice(struc
                return -ENODEV;
        }
  
-       debugf0("Detected dev %02x:%d.%d PCI ID %04x:%04x\n",
-               bus, dev_descr->dev,
-               dev_descr->func,
-               PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
+       edac_dbg(0, "Detected dev %02x:%d.%d PCI ID %04x:%04x\n",
+                bus, dev_descr->dev, dev_descr->func,
+                PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
  
        /*
         * As stated on drivers/pci/search.c, the reference count for
@@@ -1297,10 -1294,10 +1294,10 @@@ static int mci_bind_devs(struct mem_ctl
                        goto error;
                }
  
-               debugf0("Associated PCI %02x.%02d.%d with dev = %p\n",
-                       sbridge_dev->bus,
-                       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
-                       pdev);
+               edac_dbg(0, "Associated PCI %02x.%02d.%d with dev = %p\n",
+                        sbridge_dev->bus,
+                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+                        pdev);
        }
  
        /* Check if everything were registered */
@@@ -1371,7 -1368,7 +1368,7 @@@ static void sbridge_mce_output_error(st
        }
  
        /*
 -       * According with Table 15-9 of the Intel Archictecture spec vol 3A,
 +       * According with Table 15-9 of the Intel Architecture spec vol 3A,
         * memory errors should fit in this mask:
         *      000f 0000 1mmm cccc (binary)
         * where:
         * to the group of dimm's where the error may be happening.
         */
        snprintf(msg, sizeof(msg),
-                "count:%d%s%s area:%s err_code:%04x:%04x socket:%d channel_mask:%ld rank:%d",
-                core_err_cnt,
+                "%s%s area:%s err_code:%04x:%04x socket:%d channel_mask:%ld rank:%d",
                 overflow ? " OVERFLOW" : "",
                 (uncorrected_error && recoverable) ? " recoverable" : "",
                 area_type,
                 channel_mask,
                 rank);
  
-       debugf0("%s", msg);
+       edac_dbg(0, "%s\n", msg);
  
        /* FIXME: need support for channel mask */
  
        /* Call the helper to output message */
-       edac_mc_handle_error(tp_event, mci,
+       edac_mc_handle_error(tp_event, mci, core_err_cnt,
                             m->addr >> PAGE_SHIFT, m->addr & ~PAGE_MASK, 0,
                             channel, dimm, -1,
-                            optype, msg, m);
+                            optype, msg);
        return;
  err_parsing:
-       edac_mc_handle_error(tp_event, mci, 0, 0, 0,
+       edac_mc_handle_error(tp_event, mci, core_err_cnt, 0, 0, 0,
                             -1, -1, -1,
-                            msg, "", m);
+                            msg, "");
  
  }
  
@@@ -1592,8 -1588,7 +1588,7 @@@ static void sbridge_unregister_mci(stru
        struct sbridge_pvt *pvt;
  
        if (unlikely(!mci || !mci->pvt_info)) {
-               debugf0("MC: " __FILE__ ": %s(): dev = %p\n",
-                       __func__, &sbridge_dev->pdev[0]->dev);
+               edac_dbg(0, "MC: dev = %p\n", &sbridge_dev->pdev[0]->dev);
  
                sbridge_printk(KERN_ERR, "Couldn't find mci handler\n");
                return;
  
        pvt = mci->pvt_info;
  
-       debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
-               __func__, mci, &sbridge_dev->pdev[0]->dev);
+       edac_dbg(0, "MC: mci = %p, dev = %p\n",
+                mci, &sbridge_dev->pdev[0]->dev);
  
 -      mce_unregister_decode_chain(&sbridge_mce_dec);
 -
        /* Remove MC sysfs nodes */
-       edac_mc_del_mc(mci->dev);
+       edac_mc_del_mc(mci->pdev);
  
-       debugf1("%s: free mci struct\n", mci->ctl_name);
+       edac_dbg(1, "%s: free mci struct\n", mci->ctl_name);
        kfree(mci->ctl_name);
        edac_mc_free(mci);
        sbridge_dev->mci = NULL;
@@@ -1638,8 -1635,8 +1633,8 @@@ static int sbridge_register_mci(struct 
        if (unlikely(!mci))
                return -ENOMEM;
  
-       debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
-               __func__, mci, &sbridge_dev->pdev[0]->dev);
+       edac_dbg(0, "MC: mci = %p, dev = %p\n",
+                mci, &sbridge_dev->pdev[0]->dev);
  
        pvt = mci->pvt_info;
        memset(pvt, 0, sizeof(*pvt));
        get_memory_layout(mci);
  
        /* record ptr to the generic device */
-       mci->dev = &sbridge_dev->pdev[0]->dev;
+       mci->pdev = &sbridge_dev->pdev[0]->dev;
  
        /* add this new MC control structure to EDAC's list of MCs */
        if (unlikely(edac_mc_add_mc(mci))) {
-               debugf0("MC: " __FILE__
-                       ": %s(): failed edac_mc_add_mc()\n", __func__);
+               edac_dbg(0, "MC: failed edac_mc_add_mc()\n");
                rc = -EINVAL;
                goto fail0;
        }
  
 -      mce_register_decode_chain(&sbridge_mce_dec);
        return 0;
  
  fail0:
@@@ -1722,7 -1719,8 +1716,8 @@@ static int __devinit sbridge_probe(stru
        mc = 0;
  
        list_for_each_entry(sbridge_dev, &sbridge_edac_list, list) {
-               debugf0("Registering MC#%d (%d of %d)\n", mc, mc + 1, num_mc);
+               edac_dbg(0, "Registering MC#%d (%d of %d)\n",
+                        mc, mc + 1, num_mc);
                sbridge_dev->mc = mc++;
                rc = sbridge_register_mci(sbridge_dev);
                if (unlikely(rc < 0))
@@@ -1752,7 -1750,7 +1747,7 @@@ static void __devexit sbridge_remove(st
  {
        struct sbridge_dev *sbridge_dev;
  
-       debugf0(__FILE__ ": %s()\n", __func__);
+       edac_dbg(0, "\n");
  
        /*
         * we have a trouble here: pdev value for removal will be wrong, since
@@@ -1801,17 -1799,15 +1796,17 @@@ static int __init sbridge_init(void
  {
        int pci_rc;
  
-       debugf2("MC: " __FILE__ ": %s()\n", __func__);
+       edac_dbg(2, "\n");
  
        /* Ensure that the OPSTATE is set correctly for POLL or NMI */
        opstate_init();
  
        pci_rc = pci_register_driver(&sbridge_driver);
  
 -      if (pci_rc >= 0)
 +      if (pci_rc >= 0) {
 +              mce_register_decode_chain(&sbridge_mce_dec);
                return 0;
 +      }
  
        sbridge_printk(KERN_ERR, "Failed to register device with error %d.\n",
                      pci_rc);
   */
  static void __exit sbridge_exit(void)
  {
-       debugf2("MC: " __FILE__ ": %s()\n", __func__);
+       edac_dbg(2, "\n");
        pci_unregister_driver(&sbridge_driver);
 +      mce_unregister_decode_chain(&sbridge_mce_dec);
  }
  
  module_init(sbridge_init);
This page took 0.195472 seconds and 4 git commands to generate.