aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-11 19:21:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-11 19:21:12 -0400
commitd9b44fe30fb8637b23f804eab2e7afbce129d714 (patch)
treefdf3a50bf173c4914f542be9c6ef483856af33e4
parent9ebd051a7d5aa7b0ce813c3c2e5b9c851e7774b9 (diff)
parent12f0721c5a70408e86257c5c99605cf743cd44c6 (diff)
Merge tag 'edac/v4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac
Pull edac updates from Mauro Carvalho Chehab: "Two EDAC fixes for Intel systems (Haswell and Ivy Bridge)" * tag 'edac/v4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac: sb_edac: correctly fetch DIMM width on Ivy Bridge and Haswell sb_edac: look harder for DDRIO on Haswell systems
-rw-r--r--drivers/edac/sb_edac.c72
1 files changed, 60 insertions, 12 deletions
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index ca7831168298..cf1268ddef0c 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -280,6 +280,7 @@ struct sbridge_info {
280 u8 max_interleave; 280 u8 max_interleave;
281 u8 (*get_node_id)(struct sbridge_pvt *pvt); 281 u8 (*get_node_id)(struct sbridge_pvt *pvt);
282 enum mem_type (*get_memory_type)(struct sbridge_pvt *pvt); 282 enum mem_type (*get_memory_type)(struct sbridge_pvt *pvt);
283 enum dev_type (*get_width)(struct sbridge_pvt *pvt, u32 mtr);
283 struct pci_dev *pci_vtd; 284 struct pci_dev *pci_vtd;
284}; 285};
285 286
@@ -471,6 +472,9 @@ static const struct pci_id_table pci_dev_descr_ibridge_table[] = {
471#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD2 0x2f6c 472#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD2 0x2f6c
472#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD3 0x2f6d 473#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TAD3 0x2f6d
473#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO0 0x2fbd 474#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO0 0x2fbd
475#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO1 0x2fbf
476#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO2 0x2fb9
477#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO3 0x2fbb
474static const struct pci_id_descr pci_dev_descr_haswell[] = { 478static const struct pci_id_descr pci_dev_descr_haswell[] = {
475 /* first item must be the HA */ 479 /* first item must be the HA */
476 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0, 0) }, 480 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0, 0) },
@@ -488,6 +492,9 @@ static const struct pci_id_descr pci_dev_descr_haswell[] = {
488 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD3, 1) }, 492 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TAD3, 1) },
489 493
490 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO0, 1) }, 494 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO0, 1) },
495 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO1, 1) },
496 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO2, 1) },
497 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO3, 1) },
491 498
492 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TA, 1) }, 499 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_TA, 1) },
493 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_THERMAL, 1) }, 500 { PCI_DESCR(PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1_THERMAL, 1) },
@@ -762,6 +769,49 @@ out:
762 return mtype; 769 return mtype;
763} 770}
764 771
772static enum dev_type sbridge_get_width(struct sbridge_pvt *pvt, u32 mtr)
773{
774 /* there's no way to figure out */
775 return DEV_UNKNOWN;
776}
777
778static enum dev_type __ibridge_get_width(u32 mtr)
779{
780 enum dev_type type;
781
782 switch (mtr) {
783 case 3:
784 type = DEV_UNKNOWN;
785 break;
786 case 2:
787 type = DEV_X16;
788 break;
789 case 1:
790 type = DEV_X8;
791 break;
792 case 0:
793 type = DEV_X4;
794 break;
795 }
796
797 return type;
798}
799
800static enum dev_type ibridge_get_width(struct sbridge_pvt *pvt, u32 mtr)
801{
802 /*
803 * ddr3_width on the documentation but also valid for DDR4 on
804 * Haswell
805 */
806 return __ibridge_get_width(GET_BITFIELD(mtr, 7, 8));
807}
808
809static enum dev_type broadwell_get_width(struct sbridge_pvt *pvt, u32 mtr)
810{
811 /* ddr3_width on the documentation but also valid for DDR4 */
812 return __ibridge_get_width(GET_BITFIELD(mtr, 8, 9));
813}
814
765static u8 get_node_id(struct sbridge_pvt *pvt) 815static u8 get_node_id(struct sbridge_pvt *pvt)
766{ 816{
767 u32 reg; 817 u32 reg;
@@ -966,17 +1016,7 @@ static int get_dimm_config(struct mem_ctl_info *mci)
966 1016
967 dimm->nr_pages = npages; 1017 dimm->nr_pages = npages;
968 dimm->grain = 32; 1018 dimm->grain = 32;
969 switch (banks) { 1019 dimm->dtype = pvt->info.get_width(pvt, mtr);
970 case 16:
971 dimm->dtype = DEV_X16;
972 break;
973 case 8:
974 dimm->dtype = DEV_X8;
975 break;
976 case 4:
977 dimm->dtype = DEV_X4;
978 break;
979 }
980 dimm->mtype = mtype; 1020 dimm->mtype = mtype;
981 dimm->edac_mode = mode; 1021 dimm->edac_mode = mode;
982 snprintf(dimm->label, sizeof(dimm->label), 1022 snprintf(dimm->label, sizeof(dimm->label),
@@ -1869,7 +1909,11 @@ static int haswell_mci_bind_devs(struct mem_ctl_info *mci,
1869 } 1909 }
1870 break; 1910 break;
1871 case PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO0: 1911 case PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO0:
1872 pvt->pci_ddrio = pdev; 1912 case PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO1:
1913 case PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO2:
1914 case PCI_DEVICE_ID_INTEL_HASWELL_IMC_DDRIO3:
1915 if (!pvt->pci_ddrio)
1916 pvt->pci_ddrio = pdev;
1873 break; 1917 break;
1874 case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1: 1918 case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA1:
1875 pvt->pci_ha1 = pdev; 1919 pvt->pci_ha1 = pdev;
@@ -2361,6 +2405,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
2361 pvt->info.interleave_list = ibridge_interleave_list; 2405 pvt->info.interleave_list = ibridge_interleave_list;
2362 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); 2406 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
2363 pvt->info.interleave_pkg = ibridge_interleave_pkg; 2407 pvt->info.interleave_pkg = ibridge_interleave_pkg;
2408 pvt->info.get_width = ibridge_get_width;
2364 mci->ctl_name = kasprintf(GFP_KERNEL, "Ivy Bridge Socket#%d", mci->mc_idx); 2409 mci->ctl_name = kasprintf(GFP_KERNEL, "Ivy Bridge Socket#%d", mci->mc_idx);
2365 2410
2366 /* Store pci devices at mci for faster access */ 2411 /* Store pci devices at mci for faster access */
@@ -2380,6 +2425,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
2380 pvt->info.interleave_list = sbridge_interleave_list; 2425 pvt->info.interleave_list = sbridge_interleave_list;
2381 pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list); 2426 pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list);
2382 pvt->info.interleave_pkg = sbridge_interleave_pkg; 2427 pvt->info.interleave_pkg = sbridge_interleave_pkg;
2428 pvt->info.get_width = sbridge_get_width;
2383 mci->ctl_name = kasprintf(GFP_KERNEL, "Sandy Bridge Socket#%d", mci->mc_idx); 2429 mci->ctl_name = kasprintf(GFP_KERNEL, "Sandy Bridge Socket#%d", mci->mc_idx);
2384 2430
2385 /* Store pci devices at mci for faster access */ 2431 /* Store pci devices at mci for faster access */
@@ -2399,6 +2445,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
2399 pvt->info.interleave_list = ibridge_interleave_list; 2445 pvt->info.interleave_list = ibridge_interleave_list;
2400 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); 2446 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
2401 pvt->info.interleave_pkg = ibridge_interleave_pkg; 2447 pvt->info.interleave_pkg = ibridge_interleave_pkg;
2448 pvt->info.get_width = ibridge_get_width;
2402 mci->ctl_name = kasprintf(GFP_KERNEL, "Haswell Socket#%d", mci->mc_idx); 2449 mci->ctl_name = kasprintf(GFP_KERNEL, "Haswell Socket#%d", mci->mc_idx);
2403 2450
2404 /* Store pci devices at mci for faster access */ 2451 /* Store pci devices at mci for faster access */
@@ -2418,6 +2465,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
2418 pvt->info.interleave_list = ibridge_interleave_list; 2465 pvt->info.interleave_list = ibridge_interleave_list;
2419 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); 2466 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
2420 pvt->info.interleave_pkg = ibridge_interleave_pkg; 2467 pvt->info.interleave_pkg = ibridge_interleave_pkg;
2468 pvt->info.get_width = broadwell_get_width;
2421 mci->ctl_name = kasprintf(GFP_KERNEL, "Broadwell Socket#%d", mci->mc_idx); 2469 mci->ctl_name = kasprintf(GFP_KERNEL, "Broadwell Socket#%d", mci->mc_idx);
2422 2470
2423 /* Store pci devices at mci for faster access */ 2471 /* Store pci devices at mci for faster access */