mirror of https://gitee.com/openkylin/linux.git
edac: make i82443bxgx_edac coexist with intel_agp
Fix 443BX/GX MCH suppport in a EDAC. It makes i82443bxgx_edac coexist with intel_agp using the same approach as several other EDAC drivers. Tested on Intel's L443GX with redhat's 2.6.18 with whole EDAC subsystem backported a while ago. [root@host ~]# dmesg|grep -iE '(AGP|EDAC)' Linux agpgart interface v0.101 (c) Dave Jones agpgart: Detected an Intel 440GX Chipset. agpgart: AGP aperture is 64M @ 0xf8000000 EDAC MC: Ver: 2.1.0 Jun 27 2008 EDAC MC0: Giving out device to 'i82443bxgx_edac' 'I82443BXGX': DEV 0000:00:00.0 EDAC PCI0: Giving out device to module 'i82443bxgx_edac' controller 'EDAC PCI controller': DEV '0000:00:00.0' (POLLED) Signed-off-by: Vladislav Bogdanov <slava@nsys.by> Cc: Doug Thompson <norsk5@yahoo.com> Cc: Dave Airlie <airlied@linux.ie> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
25cbe53ef1
commit
53a2fe5804
|
@ -114,6 +114,12 @@ struct i82443bxgx_edacmc_error_info {
|
|||
|
||||
static struct edac_pci_ctl_info *i82443bxgx_pci;
|
||||
|
||||
static struct pci_dev *mci_pdev; /* init dev: in case that AGP code has
|
||||
* already registered driver
|
||||
*/
|
||||
|
||||
static int i82443bxgx_registered = 1;
|
||||
|
||||
static void i82443bxgx_edacmc_get_error_info(struct mem_ctl_info *mci,
|
||||
struct i82443bxgx_edacmc_error_info
|
||||
*info)
|
||||
|
@ -345,10 +351,17 @@ EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_probe1);
|
|||
static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
int rc;
|
||||
|
||||
debugf0("MC: " __FILE__ ": %s()\n", __func__);
|
||||
|
||||
/* don't need to call pci_device_enable() */
|
||||
return i82443bxgx_edacmc_probe1(pdev, ent->driver_data);
|
||||
rc = i82443bxgx_edacmc_probe1(pdev, ent->driver_data);
|
||||
|
||||
if (mci_pdev == NULL)
|
||||
mci_pdev = pci_dev_get(pdev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev)
|
||||
|
@ -387,15 +400,61 @@ static struct pci_driver i82443bxgx_edacmc_driver = {
|
|||
|
||||
static int __init i82443bxgx_edacmc_init(void)
|
||||
{
|
||||
int pci_rc;
|
||||
/* Ensure that the OPSTATE is set correctly for POLL or NMI */
|
||||
opstate_init();
|
||||
|
||||
return pci_register_driver(&i82443bxgx_edacmc_driver);
|
||||
pci_rc = pci_register_driver(&i82443bxgx_edacmc_driver);
|
||||
if (pci_rc < 0)
|
||||
goto fail0;
|
||||
|
||||
if (mci_pdev == NULL) {
|
||||
const struct pci_device_id *id = &i82443bxgx_pci_tbl[0];
|
||||
int i = 0;
|
||||
i82443bxgx_registered = 0;
|
||||
|
||||
while (mci_pdev == NULL && id->vendor != 0) {
|
||||
mci_pdev = pci_get_device(id->vendor,
|
||||
id->device, NULL);
|
||||
i++;
|
||||
id = &i82443bxgx_pci_tbl[i];
|
||||
}
|
||||
if (!mci_pdev) {
|
||||
debugf0("i82443bxgx pci_get_device fail\n");
|
||||
pci_rc = -ENODEV;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
pci_rc = i82443bxgx_edacmc_init_one(mci_pdev, i82443bxgx_pci_tbl);
|
||||
|
||||
if (pci_rc < 0) {
|
||||
debugf0("i82443bxgx init fail\n");
|
||||
pci_rc = -ENODEV;
|
||||
goto fail1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail1:
|
||||
pci_unregister_driver(&i82443bxgx_edacmc_driver);
|
||||
|
||||
fail0:
|
||||
if (mci_pdev != NULL)
|
||||
pci_dev_put(mci_pdev);
|
||||
|
||||
return pci_rc;
|
||||
}
|
||||
|
||||
static void __exit i82443bxgx_edacmc_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&i82443bxgx_edacmc_driver);
|
||||
|
||||
if (!i82443bxgx_registered)
|
||||
i82443bxgx_edacmc_remove_one(mci_pdev);
|
||||
|
||||
if (mci_pdev)
|
||||
pci_dev_put(mci_pdev);
|
||||
}
|
||||
|
||||
module_init(i82443bxgx_edacmc_init);
|
||||
|
|
Loading…
Reference in New Issue