diff options
author | Vernon Mauery <vernux@us.ibm.com> | 2010-05-18 18:02:50 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-18 19:23:56 -0400 |
commit | bd9e19ca46b54fa85141c4d20afd668379d94c81 (patch) | |
tree | 50b5927ff444a68c74895037b7267fadacdecbbe /drivers/edac | |
parent | d4d1ef4515cca074d5bbe1c63420822d6b20fe63 (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.c | 117 |
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 | ||
209 | struct pci_id_table { | ||
210 | struct pci_id_descr *descr; | ||
211 | int n_devs; | ||
212 | }; | ||
213 | |||
209 | struct i7core_dev { | 214 | struct 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 | ||
265 | struct pci_id_descr pci_dev_descr_i7core[] = { | 270 | struct 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 | ||
329 | struct 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) } | ||
361 | struct 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 | ||
1173 | static void __init i7core_xeon_pci_fixup(int dev_id) | 1216 | static 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 | ||
1310 | static int i7core_get_devices(struct pci_id_descr dev_descr[], unsigned n_devs) | 1354 | static 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 | ||
1330 | static int mci_bind_devs(struct mem_ctl_info *mci, | 1384 | static 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 | ||