lkml.org 
[lkml]   [2020]   [Aug]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.9 26/26] EDAC/ie31200: Fallback if host bridge device is already initialized
    Date
    From: Jason Baron <jbaron@akamai.com>

    [ Upstream commit 709ed1bcef12398ac1a35c149f3e582db04456c2 ]

    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 <jbaron@akamai.com>
    Cc: Borislav Petkov <bp@suse.de>
    Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
    Cc: linux-edac <linux-edac@vger.kernel.org>
    Signed-off-by: Tony Luck <tony.luck@intel.com>
    Link: https://lore.kernel.org/r/1594923911-10885-1-git-send-email-jbaron@akamai.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/edac/ie31200_edac.c | 50 ++++++++++++++++++++++++++++++++++---
    1 file changed, 47 insertions(+), 3 deletions(-)

    diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c
    index 1c88d97074951..3438b98e60948 100644
    --- a/drivers/edac/ie31200_edac.c
    +++ b/drivers/edac/ie31200_edac.c
    @@ -145,6 +145,8 @@
    (n << (28 + (2 * skl) - PAGE_SHIFT))

    static int nr_channels;
    +static struct pci_dev *mci_pdev;
    +static int ie31200_registered = 1;

    struct ie31200_priv {
    void __iomem *window;
    @@ -512,12 +514,16 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
    static int ie31200_init_one(struct pci_dev *pdev,
    const struct pci_device_id *ent)
    {
    - edac_dbg(0, "MC:\n");
    + int rc;

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

    - return ie31200_probe1(pdev, ent->driver_data);
    + return rc;
    }

    static void ie31200_remove_one(struct pci_dev *pdev)
    @@ -526,6 +532,8 @@ static void ie31200_remove_one(struct pci_dev *pdev)
    struct ie31200_priv *priv;

    edac_dbg(0, "\n");
    + pci_dev_put(mci_pdev);
    + mci_pdev = NULL;
    mci = edac_mc_del_mc(&pdev->dev);
    if (!mci)
    return;
    @@ -574,17 +582,53 @@ static struct pci_driver ie31200_driver = {

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

    - return pci_register_driver(&ie31200_driver);
    + pci_rc = pci_register_driver(&ie31200_driver);
    + if (pci_rc < 0)
    + goto fail0;
    +
    + if (!mci_pdev) {
    + ie31200_registered = 0;
    + for (i = 0; ie31200_pci_tbl[i].vendor != 0; i++) {
    + mci_pdev = pci_get_device(ie31200_pci_tbl[i].vendor,
    + ie31200_pci_tbl[i].device,
    + NULL);
    + if (mci_pdev)
    + break;
    + }
    + if (!mci_pdev) {
    + edac_dbg(0, "ie31200 pci_get_device fail\n");
    + pci_rc = -ENODEV;
    + goto fail1;
    + }
    + pci_rc = ie31200_init_one(mci_pdev, &ie31200_pci_tbl[i]);
    + if (pci_rc < 0) {
    + edac_dbg(0, "ie31200 init fail\n");
    + pci_rc = -ENODEV;
    + goto fail1;
    + }
    + }
    + return 0;
    +
    +fail1:
    + pci_unregister_driver(&ie31200_driver);
    +fail0:
    + pci_dev_put(mci_pdev);
    +
    + return pci_rc;
    }

    static void __exit ie31200_exit(void)
    {
    edac_dbg(3, "MC:\n");
    pci_unregister_driver(&ie31200_driver);
    + if (!ie31200_registered)
    + ie31200_remove_one(mci_pdev);
    }

    module_init(ie31200_init);
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-08-21 18:37    [W:3.214 / U:0.156 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site