aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-30 18:43:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-30 18:43:32 -0400
commitb48aeab65e9fc4b0c9757c5fbc1d722544eb8786 (patch)
tree0bfce428f067ca9cf06d971ba8795ad69ca610e2 /drivers
parent1bc87b00556e8f7ba30a1010471951c5b8f71114 (diff)
parent1f6189ed18cbd99d90bffdbc76c3adc54418b2fd (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp: amd64_edac: Cleanup return type of amd64_determine_edac_cap() amd64_edac: Add a fix for Erratum 505 EDAC, MCE, AMD: Simplify NB MCE decoder interface EDAC, MCE, AMD: Drop local coreid reporting EDAC, MCE, AMD: Print valid addr when reporting an error EDAC, MCE, AMD: Print CPU number when reporting the error
Diffstat (limited to 'drivers')
-rw-r--r--drivers/edac/amd64_edac.c37
-rw-r--r--drivers/edac/mce_amd.c46
-rw-r--r--drivers/edac/mce_amd.h6
3 files changed, 44 insertions, 45 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 9a8bebcf6b17..c9eee6d33e9a 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -114,10 +114,22 @@ static int f10_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val,
114 return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func); 114 return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func);
115} 115}
116 116
117/*
118 * Select DCT to which PCI cfg accesses are routed
119 */
120static void f15h_select_dct(struct amd64_pvt *pvt, u8 dct)
121{
122 u32 reg = 0;
123
124 amd64_read_pci_cfg(pvt->F1, DCT_CFG_SEL, &reg);
125 reg &= 0xfffffffe;
126 reg |= dct;
127 amd64_write_pci_cfg(pvt->F1, DCT_CFG_SEL, reg);
128}
129
117static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, 130static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val,
118 const char *func) 131 const char *func)
119{ 132{
120 u32 reg = 0;
121 u8 dct = 0; 133 u8 dct = 0;
122 134
123 if (addr >= 0x140 && addr <= 0x1a0) { 135 if (addr >= 0x140 && addr <= 0x1a0) {
@@ -125,10 +137,7 @@ static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val,
125 addr -= 0x100; 137 addr -= 0x100;
126 } 138 }
127 139
128 amd64_read_pci_cfg(pvt->F1, DCT_CFG_SEL, &reg); 140 f15h_select_dct(pvt, dct);
129 reg &= 0xfffffffe;
130 reg |= dct;
131 amd64_write_pci_cfg(pvt->F1, DCT_CFG_SEL, reg);
132 141
133 return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func); 142 return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func);
134} 143}
@@ -198,6 +207,10 @@ static int amd64_set_scrub_rate(struct mem_ctl_info *mci, u32 bw)
198 if (boot_cpu_data.x86 == 0xf) 207 if (boot_cpu_data.x86 == 0xf)
199 min_scrubrate = 0x0; 208 min_scrubrate = 0x0;
200 209
210 /* F15h Erratum #505 */
211 if (boot_cpu_data.x86 == 0x15)
212 f15h_select_dct(pvt, 0);
213
201 return __amd64_set_scrub_rate(pvt->F3, bw, min_scrubrate); 214 return __amd64_set_scrub_rate(pvt->F3, bw, min_scrubrate);
202} 215}
203 216
@@ -207,6 +220,10 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci)
207 u32 scrubval = 0; 220 u32 scrubval = 0;
208 int i, retval = -EINVAL; 221 int i, retval = -EINVAL;
209 222
223 /* F15h Erratum #505 */
224 if (boot_cpu_data.x86 == 0x15)
225 f15h_select_dct(pvt, 0);
226
210 amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval); 227 amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval);
211 228
212 scrubval = scrubval & 0x001F; 229 scrubval = scrubval & 0x001F;
@@ -751,10 +768,10 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16);
751 * Determine if the DIMMs have ECC enabled. ECC is enabled ONLY if all the DIMMs 768 * Determine if the DIMMs have ECC enabled. ECC is enabled ONLY if all the DIMMs
752 * are ECC capable. 769 * are ECC capable.
753 */ 770 */
754static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt) 771static unsigned long amd64_determine_edac_cap(struct amd64_pvt *pvt)
755{ 772{
756 u8 bit; 773 u8 bit;
757 enum dev_type edac_cap = EDAC_FLAG_NONE; 774 unsigned long edac_cap = EDAC_FLAG_NONE;
758 775
759 bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= K8_REV_F) 776 bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= K8_REV_F)
760 ? 19 777 ? 19
@@ -1953,11 +1970,9 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
1953 amd64_handle_ue(mci, m); 1970 amd64_handle_ue(mci, m);
1954} 1971}
1955 1972
1956void amd64_decode_bus_error(int node_id, struct mce *m, u32 nbcfg) 1973void amd64_decode_bus_error(int node_id, struct mce *m)
1957{ 1974{
1958 struct mem_ctl_info *mci = mcis[node_id]; 1975 __amd64_decode_bus_error(mcis[node_id], m);
1959
1960 __amd64_decode_bus_error(mci, m);
1961} 1976}
1962 1977
1963/* 1978/*
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 795cfbc0bf50..d0864d9c38ad 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -9,7 +9,7 @@ static u8 xec_mask = 0xf;
9static u8 nb_err_cpumask = 0xf; 9static u8 nb_err_cpumask = 0xf;
10 10
11static bool report_gart_errors; 11static bool report_gart_errors;
12static void (*nb_bus_decoder)(int node_id, struct mce *m, u32 nbcfg); 12static void (*nb_bus_decoder)(int node_id, struct mce *m);
13 13
14void amd_report_gart_errors(bool v) 14void amd_report_gart_errors(bool v)
15{ 15{
@@ -17,13 +17,13 @@ void amd_report_gart_errors(bool v)
17} 17}
18EXPORT_SYMBOL_GPL(amd_report_gart_errors); 18EXPORT_SYMBOL_GPL(amd_report_gart_errors);
19 19
20void amd_register_ecc_decoder(void (*f)(int, struct mce *, u32)) 20void amd_register_ecc_decoder(void (*f)(int, struct mce *))
21{ 21{
22 nb_bus_decoder = f; 22 nb_bus_decoder = f;
23} 23}
24EXPORT_SYMBOL_GPL(amd_register_ecc_decoder); 24EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
25 25
26void amd_unregister_ecc_decoder(void (*f)(int, struct mce *, u32)) 26void amd_unregister_ecc_decoder(void (*f)(int, struct mce *))
27{ 27{
28 if (nb_bus_decoder) { 28 if (nb_bus_decoder) {
29 WARN_ON(nb_bus_decoder != f); 29 WARN_ON(nb_bus_decoder != f);
@@ -592,31 +592,14 @@ static bool nb_noop_mce(u16 ec, u8 xec)
592 return false; 592 return false;
593} 593}
594 594
595void amd_decode_nb_mce(int node_id, struct mce *m, u32 nbcfg) 595void amd_decode_nb_mce(struct mce *m)
596{ 596{
597 struct cpuinfo_x86 *c = &boot_cpu_data; 597 struct cpuinfo_x86 *c = &boot_cpu_data;
598 u16 ec = EC(m->status); 598 int node_id = amd_get_nb_id(m->extcpu);
599 u8 xec = XEC(m->status, 0x1f); 599 u16 ec = EC(m->status);
600 u32 nbsh = (u32)(m->status >> 32); 600 u8 xec = XEC(m->status, 0x1f);
601 int core = -1;
602
603 pr_emerg(HW_ERR "Northbridge Error (node %d", node_id);
604
605 /* F10h, revD can disable ErrCpu[3:0] through ErrCpuVal */
606 if (c->x86 == 0x10 && c->x86_model > 7) {
607 if (nbsh & NBSH_ERR_CPU_VAL)
608 core = nbsh & nb_err_cpumask;
609 } else {
610 u8 assoc_cpus = nbsh & nb_err_cpumask;
611
612 if (assoc_cpus > 0)
613 core = fls(assoc_cpus) - 1;
614 }
615 601
616 if (core >= 0) 602 pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id);
617 pr_cont(", core %d): ", core);
618 else
619 pr_cont("): ");
620 603
621 switch (xec) { 604 switch (xec) {
622 case 0x2: 605 case 0x2:
@@ -648,7 +631,7 @@ void amd_decode_nb_mce(int node_id, struct mce *m, u32 nbcfg)
648 631
649 if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x15) 632 if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x15)
650 if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder) 633 if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
651 nb_bus_decoder(node_id, m, nbcfg); 634 nb_bus_decoder(node_id, m);
652 635
653 return; 636 return;
654 637
@@ -764,13 +747,13 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
764{ 747{
765 struct mce *m = (struct mce *)data; 748 struct mce *m = (struct mce *)data;
766 struct cpuinfo_x86 *c = &boot_cpu_data; 749 struct cpuinfo_x86 *c = &boot_cpu_data;
767 int node, ecc; 750 int ecc;
768 751
769 if (amd_filter_mce(m)) 752 if (amd_filter_mce(m))
770 return NOTIFY_STOP; 753 return NOTIFY_STOP;
771 754
772 pr_emerg(HW_ERR "MC%d_STATUS[%s|%s|%s|%s|%s", 755 pr_emerg(HW_ERR "CPU:%d\tMC%d_STATUS[%s|%s|%s|%s|%s",
773 m->bank, 756 m->extcpu, m->bank,
774 ((m->status & MCI_STATUS_OVER) ? "Over" : "-"), 757 ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
775 ((m->status & MCI_STATUS_UC) ? "UE" : "CE"), 758 ((m->status & MCI_STATUS_UC) ? "UE" : "CE"),
776 ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"), 759 ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
@@ -789,6 +772,8 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
789 772
790 pr_cont("]: 0x%016llx\n", m->status); 773 pr_cont("]: 0x%016llx\n", m->status);
791 774
775 if (m->status & MCI_STATUS_ADDRV)
776 pr_emerg(HW_ERR "\tMC%d_ADDR: 0x%016llx\n", m->bank, m->addr);
792 777
793 switch (m->bank) { 778 switch (m->bank) {
794 case 0: 779 case 0:
@@ -811,8 +796,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
811 break; 796 break;
812 797
813 case 4: 798 case 4:
814 node = amd_get_nb_id(m->extcpu); 799 amd_decode_nb_mce(m);
815 amd_decode_nb_mce(node, m, 0);
816 break; 800 break;
817 801
818 case 5: 802 case 5:
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h
index 795a3206acf5..0106747e240c 100644
--- a/drivers/edac/mce_amd.h
+++ b/drivers/edac/mce_amd.h
@@ -86,9 +86,9 @@ struct amd_decoder_ops {
86}; 86};
87 87
88void amd_report_gart_errors(bool); 88void amd_report_gart_errors(bool);
89void amd_register_ecc_decoder(void (*f)(int, struct mce *, u32)); 89void amd_register_ecc_decoder(void (*f)(int, struct mce *));
90void amd_unregister_ecc_decoder(void (*f)(int, struct mce *, u32)); 90void amd_unregister_ecc_decoder(void (*f)(int, struct mce *));
91void amd_decode_nb_mce(int, struct mce *, u32); 91void amd_decode_nb_mce(struct mce *);
92int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data); 92int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data);
93 93
94#endif /* _EDAC_MCE_AMD_H */ 94#endif /* _EDAC_MCE_AMD_H */