diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-10-20 17:33:46 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-11-01 08:01:54 -0400 |
commit | 3d78c9af78e080db1961fd30ede1720d6e6e5999 (patch) | |
tree | 97581ef0eecd358abb13988e29c21310c00a0b88 /drivers/edac | |
parent | eebf11a0166f011c5945dd30fd1779afca6c964e (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/edac')
-rw-r--r-- | drivers/edac/Kconfig | 7 | ||||
-rw-r--r-- | drivers/edac/Makefile | 1 | ||||
-rw-r--r-- | drivers/edac/sb_edac.c | 48 |
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 | ||
215 | config 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 | |||
215 | config EDAC_MPC85XX | 222 | config 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 | |||
28 | obj-$(CONFIG_EDAC_I5400) += i5400_edac.o | 28 | obj-$(CONFIG_EDAC_I5400) += i5400_edac.o |
29 | obj-$(CONFIG_EDAC_I7300) += i7300_edac.o | 29 | obj-$(CONFIG_EDAC_I7300) += i7300_edac.o |
30 | obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o | 30 | obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o |
31 | obj-$(CONFIG_EDAC_SBRIDGE) += sb_edac.o | ||
31 | obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o | 32 | obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o |
32 | obj-$(CONFIG_EDAC_E752X) += e752x_edac.o | 33 | obj-$(CONFIG_EDAC_E752X) += e752x_edac.o |
33 | obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o | 34 | obj-$(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 | */ |
1581 | static int sbridge_mce_check_error(void *priv, struct mce *mce) | 1578 | static 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 | ||
1637 | static 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; |
1736 | fail1: | ||
1737 | edac_mc_del_mc(mci->dev); | ||
1738 | 1736 | ||
1739 | fail0: | 1737 | fail0: |
1740 | kfree(mci->ctl_name); | 1738 | kfree(mci->ctl_name); |