Skip to content

Commit 709ed1b

Browse files
almostivanaegl
authored andcommitted
EDAC/ie31200: Fallback if host bridge device is already initialized
The Intel uncore driver may claim some of the pci ids from ie31200 which means that the ie31200 edac driver will not initialize them as part of pci_register_driver(). Let's add a fallback for this case to 'pci_get_device()' to get a reference on the device such that it can still be configured. This is similar in approach to other edac drivers. Signed-off-by: Jason Baron <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Mauro Carvalho Chehab <[email protected]> Cc: linux-edac <[email protected]> Signed-off-by: Tony Luck <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 0f959e1 commit 709ed1b

File tree

1 file changed

+47
-3
lines changed

1 file changed

+47
-3
lines changed

drivers/edac/ie31200_edac.c

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@
170170
(n << (28 + (2 * skl) - PAGE_SHIFT))
171171

172172
static int nr_channels;
173+
static struct pci_dev *mci_pdev;
174+
static int ie31200_registered = 1;
173175

174176
struct ie31200_priv {
175177
void __iomem *window;
@@ -538,12 +540,16 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
538540
static int ie31200_init_one(struct pci_dev *pdev,
539541
const struct pci_device_id *ent)
540542
{
541-
edac_dbg(0, "MC:\n");
543+
int rc;
542544

545+
edac_dbg(0, "MC:\n");
543546
if (pci_enable_device(pdev) < 0)
544547
return -EIO;
548+
rc = ie31200_probe1(pdev, ent->driver_data);
549+
if (rc == 0 && !mci_pdev)
550+
mci_pdev = pci_dev_get(pdev);
545551

546-
return ie31200_probe1(pdev, ent->driver_data);
552+
return rc;
547553
}
548554

549555
static void ie31200_remove_one(struct pci_dev *pdev)
@@ -552,6 +558,8 @@ static void ie31200_remove_one(struct pci_dev *pdev)
552558
struct ie31200_priv *priv;
553559

554560
edac_dbg(0, "\n");
561+
pci_dev_put(mci_pdev);
562+
mci_pdev = NULL;
555563
mci = edac_mc_del_mc(&pdev->dev);
556564
if (!mci)
557565
return;
@@ -593,17 +601,53 @@ static struct pci_driver ie31200_driver = {
593601

594602
static int __init ie31200_init(void)
595603
{
604+
int pci_rc, i;
605+
596606
edac_dbg(3, "MC:\n");
597607
/* Ensure that the OPSTATE is set correctly for POLL or NMI */
598608
opstate_init();
599609

600-
return pci_register_driver(&ie31200_driver);
610+
pci_rc = pci_register_driver(&ie31200_driver);
611+
if (pci_rc < 0)
612+
goto fail0;
613+
614+
if (!mci_pdev) {
615+
ie31200_registered = 0;
616+
for (i = 0; ie31200_pci_tbl[i].vendor != 0; i++) {
617+
mci_pdev = pci_get_device(ie31200_pci_tbl[i].vendor,
618+
ie31200_pci_tbl[i].device,
619+
NULL);
620+
if (mci_pdev)
621+
break;
622+
}
623+
if (!mci_pdev) {
624+
edac_dbg(0, "ie31200 pci_get_device fail\n");
625+
pci_rc = -ENODEV;
626+
goto fail1;
627+
}
628+
pci_rc = ie31200_init_one(mci_pdev, &ie31200_pci_tbl[i]);
629+
if (pci_rc < 0) {
630+
edac_dbg(0, "ie31200 init fail\n");
631+
pci_rc = -ENODEV;
632+
goto fail1;
633+
}
634+
}
635+
return 0;
636+
637+
fail1:
638+
pci_unregister_driver(&ie31200_driver);
639+
fail0:
640+
pci_dev_put(mci_pdev);
641+
642+
return pci_rc;
601643
}
602644

603645
static void __exit ie31200_exit(void)
604646
{
605647
edac_dbg(3, "MC:\n");
606648
pci_unregister_driver(&ie31200_driver);
649+
if (!ie31200_registered)
650+
ie31200_remove_one(mci_pdev);
607651
}
608652

609653
module_init(ie31200_init);

0 commit comments

Comments
 (0)