aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorVernon Mauery <vernux@us.ibm.com>2010-05-18 18:02:50 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-18 19:23:56 -0400
commitbd9e19ca46b54fa85141c4d20afd668379d94c81 (patch)
tree50b5927ff444a68c74895037b7267fadacdecbbe /drivers/edac
parentd4d1ef4515cca074d5bbe1c63420822d6b20fe63 (diff)
Add support for Westmere to i7core_edac driver
This adds new PCI IDs for the Westmere's memory controller devices and modifies the i7core_edac driver to be able to probe both Nehalem and Westmere processors. Signed-off-by: Vernon Mauery <vernux@us.ibm.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/i7core_edac.c117
1 files changed, 80 insertions, 37 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 3e2b5379bc05..8d63b0046480 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -206,6 +206,11 @@ struct pci_id_descr {
206 int optional; 206 int optional;
207}; 207};
208 208
209struct pci_id_table {
210 struct pci_id_descr *descr;
211 int n_devs;
212};
213
209struct i7core_dev { 214struct i7core_dev {
210 struct list_head list; 215 struct list_head list;
211 u8 socket; 216 u8 socket;
@@ -262,7 +267,7 @@ static DEFINE_MUTEX(i7core_edac_lock);
262 .func = (function), \ 267 .func = (function), \
263 .dev_id = (device_id) 268 .dev_id = (device_id)
264 269
265struct pci_id_descr pci_dev_descr_i7core[] = { 270struct pci_id_descr pci_dev_descr_i7core_nehalem[] = {
266 /* Memory controller */ 271 /* Memory controller */
267 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, 272 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) },
268 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, 273 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) },
@@ -321,6 +326,44 @@ struct pci_id_descr pci_dev_descr_lynnfield[] = {
321 { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) }, 326 { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) },
322}; 327};
323 328
329struct pci_id_descr pci_dev_descr_i7core_westmere[] = {
330 /* Memory controller */
331 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2) },
332 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2) },
333 /* Exists only for RDIMM */
334 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_RAS_REV2), .optional = 1 },
335 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST_REV2) },
336
337 /* Channel 0 */
338 { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL_REV2) },
339 { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR_REV2) },
340 { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK_REV2) },
341 { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC_REV2) },
342
343 /* Channel 1 */
344 { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL_REV2) },
345 { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR_REV2) },
346 { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK_REV2) },
347 { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC_REV2) },
348
349 /* Channel 2 */
350 { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_CTRL_REV2) },
351 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2) },
352 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2) },
353 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2) },
354
355 /* Generic Non-core registers */
356 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2) },
357
358};
359
360#define PCI_ID_TABLE_ENTRY(A) { A, ARRAY_SIZE(A) }
361struct pci_id_table pci_dev_table[] = {
362 PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem),
363 PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield),
364 PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere),
365};
366
324/* 367/*
325 * pci_device_id table for which devices we are looking for 368 * pci_device_id table for which devices we are looking for
326 */ 369 */
@@ -1170,7 +1213,7 @@ static void i7core_put_all_devices(void)
1170 i7core_put_devices(i7core_dev); 1213 i7core_put_devices(i7core_dev);
1171} 1214}
1172 1215
1173static void __init i7core_xeon_pci_fixup(int dev_id) 1216static void __init i7core_xeon_pci_fixup(struct pci_id_table *table)
1174{ 1217{
1175 struct pci_dev *pdev = NULL; 1218 struct pci_dev *pdev = NULL;
1176 int i; 1219 int i;
@@ -1179,10 +1222,13 @@ static void __init i7core_xeon_pci_fixup(int dev_id)
1179 * aren't announced by acpi. So, we need to use a legacy scan probing 1222 * aren't announced by acpi. So, we need to use a legacy scan probing
1180 * to detect them 1223 * to detect them
1181 */ 1224 */
1182 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); 1225 while (table && table->descr) {
1183 if (unlikely(!pdev)) { 1226 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, table->descr[0].dev_id, NULL);
1184 for (i = 0; i < MAX_SOCKET_BUSES; i++) 1227 if (unlikely(!pdev)) {
1185 pcibios_scan_specific_bus(255-i); 1228 for (i = 0; i < MAX_SOCKET_BUSES; i++)
1229 pcibios_scan_specific_bus(255-i);
1230 }
1231 table++;
1186 } 1232 }
1187} 1233}
1188 1234
@@ -1213,15 +1259,10 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno,
1213 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 1259 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1214 PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); 1260 PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev);
1215 1261
1216 if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) { 1262 if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev)
1217 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 1263 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1218 PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, 1264 PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT,
1219 *prev); 1265 *prev);
1220 if (!pdev)
1221 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1222 PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2,
1223 *prev);
1224 }
1225 1266
1226 if (!pdev) { 1267 if (!pdev) {
1227 if (*prev) { 1268 if (*prev) {
@@ -1232,6 +1273,9 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno,
1232 if (dev_descr->optional) 1273 if (dev_descr->optional)
1233 return 0; 1274 return 0;
1234 1275
1276 if (devno == 0)
1277 return -ENODEV;
1278
1235 i7core_printk(KERN_ERR, 1279 i7core_printk(KERN_ERR,
1236 "Device not found: dev %02x.%d PCI ID %04x:%04x\n", 1280 "Device not found: dev %02x.%d PCI ID %04x:%04x\n",
1237 dev_descr->dev, dev_descr->func, 1281 dev_descr->dev, dev_descr->func,
@@ -1307,24 +1351,34 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno,
1307 return 0; 1351 return 0;
1308} 1352}
1309 1353
1310static int i7core_get_devices(struct pci_id_descr dev_descr[], unsigned n_devs) 1354static int i7core_get_devices(struct pci_id_table *table)
1311{ 1355{
1312 int i, rc; 1356 int i, rc;
1313 struct pci_dev *pdev = NULL; 1357 struct pci_dev *pdev = NULL;
1314 1358 struct pci_id_descr *dev_descr;
1315 for (i = 0; i < n_devs; i++) { 1359
1316 pdev = NULL; 1360 while (table && table->descr) {
1317 do { 1361 dev_descr = table->descr;
1318 rc = i7core_get_onedevice(&pdev, i, &dev_descr[i], 1362 for (i = 0; i < table->n_devs; i++) {
1319 n_devs); 1363 pdev = NULL;
1320 if (rc < 0) { 1364 do {
1321 i7core_put_all_devices(); 1365 rc = i7core_get_onedevice(&pdev, i, &dev_descr[i],
1322 return -ENODEV; 1366 table->n_devs);
1323 } 1367 if (rc < 0) {
1324 } while (pdev); 1368 if (i == 0) {
1369 i = table->n_devs;
1370 break;
1371 }
1372 i7core_put_all_devices();
1373 return -ENODEV;
1374 }
1375 } while (pdev);
1376 }
1377 table++;
1325 } 1378 }
1326 1379
1327 return 0; 1380 return 0;
1381 return 0;
1328} 1382}
1329 1383
1330static int mci_bind_devs(struct mem_ctl_info *mci, 1384static int mci_bind_devs(struct mem_ctl_info *mci,
@@ -1884,18 +1938,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev,
1884 /* get the pci devices we want to reserve for our use */ 1938 /* get the pci devices we want to reserve for our use */
1885 mutex_lock(&i7core_edac_lock); 1939 mutex_lock(&i7core_edac_lock);
1886 1940
1887 if (pdev->device == PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0) { 1941 rc = i7core_get_devices(pci_dev_table);
1888 printk(KERN_INFO "i7core_edac: detected a "
1889 "Lynnfield processor\n");
1890 rc = i7core_get_devices(pci_dev_descr_lynnfield,
1891 ARRAY_SIZE(pci_dev_descr_lynnfield));
1892 } else {
1893 printk(KERN_INFO "i7core_edac: detected a "
1894 "Nehalem/Nehalem-EP processor\n");
1895 rc = i7core_get_devices(pci_dev_descr_i7core,
1896 ARRAY_SIZE(pci_dev_descr_i7core));
1897 }
1898
1899 if (unlikely(rc < 0)) 1942 if (unlikely(rc < 0))
1900 goto fail0; 1943 goto fail0;
1901 1944
@@ -1994,7 +2037,7 @@ static int __init i7core_init(void)
1994 /* Ensure that the OPSTATE is set correctly for POLL or NMI */ 2037 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1995 opstate_init(); 2038 opstate_init();
1996 2039
1997 i7core_xeon_pci_fixup(pci_dev_descr_i7core[0].dev_id); 2040 i7core_xeon_pci_fixup(pci_dev_table);
1998 2041
1999 pci_rc = pci_register_driver(&i7core_driver); 2042 pci_rc = pci_register_driver(&i7core_driver);
2000 2043