aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/i82443bxgx_edac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/i82443bxgx_edac.c')
-rw-r--r--drivers/edac/i82443bxgx_edac.c63
1 files changed, 61 insertions, 2 deletions
diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c
index c5305e3ee434..577760a82a0f 100644
--- a/drivers/edac/i82443bxgx_edac.c
+++ b/drivers/edac/i82443bxgx_edac.c
@@ -114,6 +114,12 @@ struct i82443bxgx_edacmc_error_info {
114 114
115static struct edac_pci_ctl_info *i82443bxgx_pci; 115static struct edac_pci_ctl_info *i82443bxgx_pci;
116 116
117static struct pci_dev *mci_pdev; /* init dev: in case that AGP code has
118 * already registered driver
119 */
120
121static int i82443bxgx_registered = 1;
122
117static void i82443bxgx_edacmc_get_error_info(struct mem_ctl_info *mci, 123static void i82443bxgx_edacmc_get_error_info(struct mem_ctl_info *mci,
118 struct i82443bxgx_edacmc_error_info 124 struct i82443bxgx_edacmc_error_info
119 *info) 125 *info)
@@ -345,10 +351,17 @@ EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_probe1);
345static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev, 351static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev,
346 const struct pci_device_id *ent) 352 const struct pci_device_id *ent)
347{ 353{
354 int rc;
355
348 debugf0("MC: " __FILE__ ": %s()\n", __func__); 356 debugf0("MC: " __FILE__ ": %s()\n", __func__);
349 357
350 /* don't need to call pci_device_enable() */ 358 /* don't need to call pci_device_enable() */
351 return i82443bxgx_edacmc_probe1(pdev, ent->driver_data); 359 rc = i82443bxgx_edacmc_probe1(pdev, ent->driver_data);
360
361 if (mci_pdev == NULL)
362 mci_pdev = pci_dev_get(pdev);
363
364 return rc;
352} 365}
353 366
354static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev) 367static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev)
@@ -387,15 +400,61 @@ static struct pci_driver i82443bxgx_edacmc_driver = {
387 400
388static int __init i82443bxgx_edacmc_init(void) 401static int __init i82443bxgx_edacmc_init(void)
389{ 402{
403 int pci_rc;
390 /* Ensure that the OPSTATE is set correctly for POLL or NMI */ 404 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
391 opstate_init(); 405 opstate_init();
392 406
393 return pci_register_driver(&i82443bxgx_edacmc_driver); 407 pci_rc = pci_register_driver(&i82443bxgx_edacmc_driver);
408 if (pci_rc < 0)
409 goto fail0;
410
411 if (mci_pdev == NULL) {
412 const struct pci_device_id *id = &i82443bxgx_pci_tbl[0];
413 int i = 0;
414 i82443bxgx_registered = 0;
415
416 while (mci_pdev == NULL && id->vendor != 0) {
417 mci_pdev = pci_get_device(id->vendor,
418 id->device, NULL);
419 i++;
420 id = &i82443bxgx_pci_tbl[i];
421 }
422 if (!mci_pdev) {
423 debugf0("i82443bxgx pci_get_device fail\n");
424 pci_rc = -ENODEV;
425 goto fail1;
426 }
427
428 pci_rc = i82443bxgx_edacmc_init_one(mci_pdev, i82443bxgx_pci_tbl);
429
430 if (pci_rc < 0) {
431 debugf0("i82443bxgx init fail\n");
432 pci_rc = -ENODEV;
433 goto fail1;
434 }
435 }
436
437 return 0;
438
439fail1:
440 pci_unregister_driver(&i82443bxgx_edacmc_driver);
441
442fail0:
443 if (mci_pdev != NULL)
444 pci_dev_put(mci_pdev);
445
446 return pci_rc;
394} 447}
395 448
396static void __exit i82443bxgx_edacmc_exit(void) 449static void __exit i82443bxgx_edacmc_exit(void)
397{ 450{
398 pci_unregister_driver(&i82443bxgx_edacmc_driver); 451 pci_unregister_driver(&i82443bxgx_edacmc_driver);
452
453 if (!i82443bxgx_registered)
454 i82443bxgx_edacmc_remove_one(mci_pdev);
455
456 if (mci_pdev)
457 pci_dev_put(mci_pdev);
399} 458}
400 459
401module_init(i82443bxgx_edacmc_init); 460module_init(i82443bxgx_edacmc_init);