aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2011-10-20 17:33:46 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-11-01 08:01:54 -0400
commit3d78c9af78e080db1961fd30ede1720d6e6e5999 (patch)
tree97581ef0eecd358abb13988e29c21310c00a0b88 /drivers
parenteebf11a0166f011c5945dd30fd1779afca6c964e (diff)
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: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/edac/Kconfig7
-rw-r--r--drivers/edac/Makefile1
-rw-r--r--drivers/edac/sb_edac.c48
3 files changed, 31 insertions, 25 deletions
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index d057d6c40208..15e453577213 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -212,6 +212,13 @@ config EDAC_I7300
212 Support for error detection and correction the Intel 212 Support for error detection and correction the Intel
213 Clarksboro MCH (Intel 7300 chipset). 213 Clarksboro MCH (Intel 7300 chipset).
214 214
215config EDAC_SBRIDGE
216 tristate "Intel Sandy-Bridge Integrated MC"
217 depends on EDAC_MM_EDAC && PCI && X86 && X86_MCE_INTEL
218 help
219 Support for error detection and correction the Intel
220 Sandy Bridge Integrated Memory Controller.
221
215config EDAC_MPC85XX 222config EDAC_MPC85XX
216 tristate "Freescale MPC83xx / MPC85xx" 223 tristate "Freescale MPC83xx / MPC85xx"
217 depends on EDAC_MM_EDAC && FSL_SOC && (PPC_83xx || PPC_85xx) 224 depends on EDAC_MM_EDAC && FSL_SOC && (PPC_83xx || PPC_85xx)
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index b06a9b11a5f6..196a63dd37c5 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_EDAC_I5100) += i5100_edac.o
28obj-$(CONFIG_EDAC_I5400) += i5400_edac.o 28obj-$(CONFIG_EDAC_I5400) += i5400_edac.o
29obj-$(CONFIG_EDAC_I7300) += i7300_edac.o 29obj-$(CONFIG_EDAC_I7300) += i7300_edac.o
30obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o 30obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o
31obj-$(CONFIG_EDAC_SBRIDGE) += sb_edac.o
31obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o 32obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o
32obj-$(CONFIG_EDAC_E752X) += e752x_edac.o 33obj-$(CONFIG_EDAC_E752X) += e752x_edac.o
33obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o 34obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 785c2769f05b..8118f12cb8c7 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -18,10 +18,10 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/edac.h> 19#include <linux/edac.h>
20#include <linux/mmzone.h> 20#include <linux/mmzone.h>
21#include <linux/edac_mce.h>
22#include <linux/smp.h> 21#include <linux/smp.h>
23#include <linux/bitmap.h> 22#include <linux/bitmap.h>
24#include <asm/processor.h> 23#include <asm/processor.h>
24#include <asm/mce.h>
25 25
26#include "edac_core.h" 26#include "edac_core.h"
27 27
@@ -318,9 +318,6 @@ struct sbridge_pvt {
318 /* Memory type detection */ 318 /* Memory type detection */
319 bool is_mirrored, is_lockstep, is_close_pg; 319 bool is_mirrored, is_lockstep, is_close_pg;
320 320
321 /* mcelog glue */
322 struct edac_mce edac_mce;
323
324 /* Fifo double buffers */ 321 /* Fifo double buffers */
325 struct mce mce_entry[MCE_LOG_LEN]; 322 struct mce mce_entry[MCE_LOG_LEN];
326 struct mce mce_outentry[MCE_LOG_LEN]; 323 struct mce mce_outentry[MCE_LOG_LEN];
@@ -1578,10 +1575,17 @@ static void sbridge_check_error(struct mem_ctl_info *mci)
1578 * WARNING: As this routine should be called at NMI time, extra care should 1575 * WARNING: As this routine should be called at NMI time, extra care should
1579 * be taken to avoid deadlocks, and to be as fast as possible. 1576 * be taken to avoid deadlocks, and to be as fast as possible.
1580 */ 1577 */
1581static int sbridge_mce_check_error(void *priv, struct mce *mce) 1578static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,
1579 void *data)
1582{ 1580{
1583 struct mem_ctl_info *mci = priv; 1581 struct mce *mce = (struct mce *)data;
1584 struct sbridge_pvt *pvt = mci->pvt_info; 1582 struct mem_ctl_info *mci;
1583 struct sbridge_pvt *pvt;
1584
1585 mci = get_mci_for_node_id(mce->socketid);
1586 if (!mci)
1587 return NOTIFY_BAD;
1588 pvt = mci->pvt_info;
1585 1589
1586 /* 1590 /*
1587 * Just let mcelog handle it if the error is 1591 * 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 * bit 12 has an special meaning. 1594 * bit 12 has an special meaning.
1591 */ 1595 */
1592 if ((mce->status & 0xefff) >> 7 != 1) 1596 if ((mce->status & 0xefff) >> 7 != 1)
1593 return 0; 1597 return NOTIFY_DONE;
1594 1598
1595 printk("sbridge: HANDLING MCE MEMORY ERROR\n"); 1599 printk("sbridge: HANDLING MCE MEMORY ERROR\n");
1596 1600
@@ -1607,14 +1611,14 @@ static int sbridge_mce_check_error(void *priv, struct mce *mce)
1607#ifdef CONFIG_SMP 1611#ifdef CONFIG_SMP
1608 /* Only handle if it is the right mc controller */ 1612 /* Only handle if it is the right mc controller */
1609 if (cpu_data(mce->cpu).phys_proc_id != pvt->sbridge_dev->mc) 1613 if (cpu_data(mce->cpu).phys_proc_id != pvt->sbridge_dev->mc)
1610 return 0; 1614 return NOTIFY_DONE;
1611#endif 1615#endif
1612 1616
1613 smp_rmb(); 1617 smp_rmb();
1614 if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { 1618 if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) {
1615 smp_wmb(); 1619 smp_wmb();
1616 pvt->mce_overrun++; 1620 pvt->mce_overrun++;
1617 return 0; 1621 return NOTIFY_DONE;
1618 } 1622 }
1619 1623
1620 /* Copy memory error at the ringbuffer */ 1624 /* Copy memory error at the ringbuffer */
@@ -1627,9 +1631,13 @@ static int sbridge_mce_check_error(void *priv, struct mce *mce)
1627 sbridge_check_error(mci); 1631 sbridge_check_error(mci);
1628 1632
1629 /* Advice mcelog that the error were handled */ 1633 /* Advice mcelog that the error were handled */
1630 return 1; 1634 return NOTIFY_STOP;
1631} 1635}
1632 1636
1637static struct notifier_block sbridge_mce_dec = {
1638 .notifier_call = sbridge_mce_check_error,
1639};
1640
1633/**************************************************************************** 1641/****************************************************************************
1634 EDAC register/unregister logic 1642 EDAC register/unregister logic
1635 ****************************************************************************/ 1643 ****************************************************************************/
@@ -1652,8 +1660,8 @@ static void sbridge_unregister_mci(struct sbridge_dev *sbridge_dev)
1652 debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n", 1660 debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
1653 __func__, mci, &sbridge_dev->pdev[0]->dev); 1661 __func__, mci, &sbridge_dev->pdev[0]->dev);
1654 1662
1655 /* Disable MCE NMI handler */ 1663 atomic_notifier_chain_unregister(&x86_mce_decoder_chain,
1656 edac_mce_unregister(&pvt->edac_mce); 1664 &sbridge_mce_dec);
1657 1665
1658 /* Remove MC sysfs nodes */ 1666 /* Remove MC sysfs nodes */
1659 edac_mc_del_mc(mci->dev); 1667 edac_mc_del_mc(mci->dev);
@@ -1722,19 +1730,9 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev)
1722 goto fail0; 1730 goto fail0;
1723 } 1731 }
1724 1732
1725 /* Registers on edac_mce in order to receive memory errors */ 1733 atomic_notifier_chain_register(&x86_mce_decoder_chain,
1726 pvt->edac_mce.priv = mci; 1734 &sbridge_mce_dec);
1727 pvt->edac_mce.check_error = sbridge_mce_check_error;
1728 rc = edac_mce_register(&pvt->edac_mce);
1729 if (unlikely(rc < 0)) {
1730 debugf0("MC: " __FILE__
1731 ": %s(): failed edac_mce_register()\n", __func__);
1732 goto fail1;
1733 }
1734
1735 return 0; 1735 return 0;
1736fail1:
1737 edac_mc_del_mc(mci->dev);
1738 1736
1739fail0: 1737fail0:
1740 kfree(mci->ctl_name); 1738 kfree(mci->ctl_name);