Commit 3d78c9af authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

edac: sb_edac: Add it to the building system

Some changes on it were required due to changeset cd90cc84c6bf0, that
changed the glue with the MCE logic.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent eebf11a0
...@@ -212,6 +212,13 @@ config EDAC_I7300 ...@@ -212,6 +212,13 @@ config EDAC_I7300
Support for error detection and correction the Intel Support for error detection and correction the Intel
Clarksboro MCH (Intel 7300 chipset). Clarksboro MCH (Intel 7300 chipset).
config EDAC_SBRIDGE
tristate "Intel Sandy-Bridge Integrated MC"
depends on EDAC_MM_EDAC && PCI && X86 && X86_MCE_INTEL
help
Support for error detection and correction the Intel
Sandy Bridge Integrated Memory Controller.
config EDAC_MPC85XX config EDAC_MPC85XX
tristate "Freescale MPC83xx / MPC85xx" tristate "Freescale MPC83xx / MPC85xx"
depends on EDAC_MM_EDAC && FSL_SOC && (PPC_83xx || PPC_85xx) depends on EDAC_MM_EDAC && FSL_SOC && (PPC_83xx || PPC_85xx)
......
...@@ -28,6 +28,7 @@ obj-$(CONFIG_EDAC_I5100) += i5100_edac.o ...@@ -28,6 +28,7 @@ obj-$(CONFIG_EDAC_I5100) += i5100_edac.o
obj-$(CONFIG_EDAC_I5400) += i5400_edac.o obj-$(CONFIG_EDAC_I5400) += i5400_edac.o
obj-$(CONFIG_EDAC_I7300) += i7300_edac.o obj-$(CONFIG_EDAC_I7300) += i7300_edac.o
obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o
obj-$(CONFIG_EDAC_SBRIDGE) += sb_edac.o
obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o
obj-$(CONFIG_EDAC_E752X) += e752x_edac.o obj-$(CONFIG_EDAC_E752X) += e752x_edac.o
obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o
......
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/edac.h> #include <linux/edac.h>
#include <linux/mmzone.h> #include <linux/mmzone.h>
#include <linux/edac_mce.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/mce.h>
#include "edac_core.h" #include "edac_core.h"
...@@ -318,9 +318,6 @@ struct sbridge_pvt { ...@@ -318,9 +318,6 @@ struct sbridge_pvt {
/* Memory type detection */ /* Memory type detection */
bool is_mirrored, is_lockstep, is_close_pg; bool is_mirrored, is_lockstep, is_close_pg;
/* mcelog glue */
struct edac_mce edac_mce;
/* Fifo double buffers */ /* Fifo double buffers */
struct mce mce_entry[MCE_LOG_LEN]; struct mce mce_entry[MCE_LOG_LEN];
struct mce mce_outentry[MCE_LOG_LEN]; struct mce mce_outentry[MCE_LOG_LEN];
...@@ -1578,10 +1575,17 @@ static void sbridge_check_error(struct mem_ctl_info *mci) ...@@ -1578,10 +1575,17 @@ static void sbridge_check_error(struct mem_ctl_info *mci)
* WARNING: As this routine should be called at NMI time, extra care should * 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. * be taken to avoid deadlocks, and to be as fast as possible.
*/ */
static int sbridge_mce_check_error(void *priv, struct mce *mce) static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,
void *data)
{ {
struct mem_ctl_info *mci = priv; struct mce *mce = (struct mce *)data;
struct sbridge_pvt *pvt = mci->pvt_info; struct mem_ctl_info *mci;
struct sbridge_pvt *pvt;
mci = get_mci_for_node_id(mce->socketid);
if (!mci)
return NOTIFY_BAD;
pvt = mci->pvt_info;
/* /*
* Just let mcelog handle it if the error is * Just let mcelog handle it if the error is
...@@ -1590,7 +1594,7 @@ static int sbridge_mce_check_error(void *priv, struct mce *mce) ...@@ -1590,7 +1594,7 @@ static int sbridge_mce_check_error(void *priv, struct mce *mce)
* bit 12 has an special meaning. * bit 12 has an special meaning.
*/ */
if ((mce->status & 0xefff) >> 7 != 1) if ((mce->status & 0xefff) >> 7 != 1)
return 0; return NOTIFY_DONE;
printk("sbridge: HANDLING MCE MEMORY ERROR\n"); printk("sbridge: HANDLING MCE MEMORY ERROR\n");
...@@ -1607,14 +1611,14 @@ static int sbridge_mce_check_error(void *priv, struct mce *mce) ...@@ -1607,14 +1611,14 @@ static int sbridge_mce_check_error(void *priv, struct mce *mce)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Only handle if it is the right mc controller */ /* Only handle if it is the right mc controller */
if (cpu_data(mce->cpu).phys_proc_id != pvt->sbridge_dev->mc) if (cpu_data(mce->cpu).phys_proc_id != pvt->sbridge_dev->mc)
return 0; return NOTIFY_DONE;
#endif #endif
smp_rmb(); smp_rmb();
if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) {
smp_wmb(); smp_wmb();
pvt->mce_overrun++; pvt->mce_overrun++;
return 0; return NOTIFY_DONE;
} }
/* Copy memory error at the ringbuffer */ /* Copy memory error at the ringbuffer */
...@@ -1627,9 +1631,13 @@ static int sbridge_mce_check_error(void *priv, struct mce *mce) ...@@ -1627,9 +1631,13 @@ static int sbridge_mce_check_error(void *priv, struct mce *mce)
sbridge_check_error(mci); sbridge_check_error(mci);
/* Advice mcelog that the error were handled */ /* Advice mcelog that the error were handled */
return 1; return NOTIFY_STOP;
} }
static struct notifier_block sbridge_mce_dec = {
.notifier_call = sbridge_mce_check_error,
};
/**************************************************************************** /****************************************************************************
EDAC register/unregister logic EDAC register/unregister logic
****************************************************************************/ ****************************************************************************/
...@@ -1652,8 +1660,8 @@ static void sbridge_unregister_mci(struct sbridge_dev *sbridge_dev) ...@@ -1652,8 +1660,8 @@ static void sbridge_unregister_mci(struct sbridge_dev *sbridge_dev)
debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n", debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
__func__, mci, &sbridge_dev->pdev[0]->dev); __func__, mci, &sbridge_dev->pdev[0]->dev);
/* Disable MCE NMI handler */ atomic_notifier_chain_unregister(&x86_mce_decoder_chain,
edac_mce_unregister(&pvt->edac_mce); &sbridge_mce_dec);
/* Remove MC sysfs nodes */ /* Remove MC sysfs nodes */
edac_mc_del_mc(mci->dev); edac_mc_del_mc(mci->dev);
...@@ -1722,19 +1730,9 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev) ...@@ -1722,19 +1730,9 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev)
goto fail0; goto fail0;
} }
/* Registers on edac_mce in order to receive memory errors */ atomic_notifier_chain_register(&x86_mce_decoder_chain,
pvt->edac_mce.priv = mci; &sbridge_mce_dec);
pvt->edac_mce.check_error = sbridge_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;
}
return 0; return 0;
fail1:
edac_mc_del_mc(mci->dev);
fail0: fail0:
kfree(mci->ctl_name); kfree(mci->ctl_name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment