i7core_edac: Drop the edac_mce facility
[pandora-kernel.git] / drivers / edac / i7core_edac.c
index 764207e..0bddc27 100644 (file)
@@ -33,8 +33,8 @@
 #include <linux/delay.h>
 #include <linux/edac.h>
 #include <linux/mmzone.h>
-#include <linux/edac_mce.h>
 #include <linux/smp.h>
+#include <asm/mce.h>
 #include <asm/processor.h>
 
 #include "edac_core.h"
@@ -265,9 +265,6 @@ struct i7core_pvt {
 
        bool            is_registered, enable_scrub;
 
-       /* mcelog glue */
-       struct edac_mce         edac_mce;
-
        /* Fifo double buffers */
        struct mce              mce_entry[MCE_LOG_LEN];
        struct mce              mce_outentry[MCE_LOG_LEN];
@@ -1899,33 +1896,43 @@ check_ce_error:
  * WARNING: As this routine should be called at NMI time, extra care should
  * be taken to avoid deadlocks, and to be as fast as possible.
  */
-static int i7core_mce_check_error(void *priv, struct mce *mce)
+static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val,
+                                 void *data)
 {
-       struct mem_ctl_info *mci = priv;
-       struct i7core_pvt *pvt = mci->pvt_info;
+       struct mce *mce = (struct mce *)data;
+       struct i7core_dev *i7_dev;
+       struct mem_ctl_info *mci;
+       struct i7core_pvt *pvt;
+
+       i7_dev = get_i7core_dev(mce->socketid);
+       if (!i7_dev)
+               return NOTIFY_BAD;
+
+       mci = i7_dev->mci;
+       pvt = mci->pvt_info;
 
        /*
         * Just let mcelog handle it if the error is
         * outside the memory controller
         */
        if (((mce->status & 0xffff) >> 7) != 1)
-               return 0;
+               return NOTIFY_DONE;
 
        /* Bank 8 registers are the only ones that we know how to handle */
        if (mce->bank != 8)
-               return 0;
+               return NOTIFY_DONE;
 
 #ifdef CONFIG_SMP
        /* Only handle if it is the right mc controller */
        if (mce->socketid != pvt->i7core_dev->socket)
-               return 0;
+               return NOTIFY_DONE;
 #endif
 
        smp_rmb();
        if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) {
                smp_wmb();
                pvt->mce_overrun++;
-               return 0;
+               return NOTIFY_DONE;
        }
 
        /* Copy memory error at the ringbuffer */
@@ -1938,9 +1945,13 @@ static int i7core_mce_check_error(void *priv, struct mce *mce)
                i7core_check_error(mci);
 
        /* Advise mcelog that the errors were handled */
-       return 1;
+       return NOTIFY_STOP;
 }
 
+static struct notifier_block i7_mce_dec = {
+       .notifier_call  = i7core_mce_check_error,
+};
+
 /*
  * set_sdram_scrub_rate                This routine sets byte/sec bandwidth scrub rate
  *                             to hardware according to SCRUBINTERVAL formula
@@ -2093,8 +2104,7 @@ static void i7core_unregister_mci(struct i7core_dev *i7core_dev)
        if (pvt->enable_scrub)
                disable_sdram_scrub_setting(mci);
 
-       /* Disable MCE NMI handler */
-       edac_mce_unregister(&pvt->edac_mce);
+       atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &i7_mce_dec);
 
        /* Disable EDAC polling */
        i7core_pci_ctl_release(pvt);
@@ -2193,21 +2203,10 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev)
        /* allocating generic PCI control info */
        i7core_pci_ctl_create(pvt);
 
-       /* Registers on edac_mce in order to receive memory errors */
-       pvt->edac_mce.priv = mci;
-       pvt->edac_mce.check_error = i7core_mce_check_error;
-       rc = edac_mce_register(&pvt->edac_mce);
-       if (unlikely(rc < 0)) {
-               debugf0("MC: " __FILE__
-                       ": %s(): failed edac_mce_register()\n", __func__);
-               goto fail1;
-       }
+       atomic_notifier_chain_register(&x86_mce_decoder_chain, &i7_mce_dec);
 
        return 0;
 
-fail1:
-       i7core_pci_ctl_release(pvt);
-       edac_mc_del_mc(mci->dev);
 fail0:
        kfree(mci->ctl_name);
        edac_mc_free(mci);