Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * amd8111_edac.c, AMD8111 Hyper Transport chip EDAC kernel module
0004  *
0005  * Copyright (c) 2008 Wind River Systems, Inc.
0006  *
0007  * Authors: Cao Qingtao <qingtao.cao@windriver.com>
0008  *      Benjamin Walsh <benjamin.walsh@windriver.com>
0009  *      Hu Yongqi <yongqi.hu@windriver.com>
0010  */
0011 
0012 #include <linux/module.h>
0013 #include <linux/init.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/bitops.h>
0016 #include <linux/edac.h>
0017 #include <linux/pci_ids.h>
0018 #include <asm/io.h>
0019 
0020 #include "edac_module.h"
0021 #include "amd8111_edac.h"
0022 
0023 #define AMD8111_EDAC_REVISION   " Ver: 1.0.0"
0024 #define AMD8111_EDAC_MOD_STR    "amd8111_edac"
0025 
0026 #define PCI_DEVICE_ID_AMD_8111_PCI  0x7460
0027 
0028 enum amd8111_edac_devs {
0029     LPC_BRIDGE = 0,
0030 };
0031 
0032 enum amd8111_edac_pcis {
0033     PCI_BRIDGE = 0,
0034 };
0035 
0036 /* Wrapper functions for accessing PCI configuration space */
0037 static int edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
0038 {
0039     int ret;
0040 
0041     ret = pci_read_config_dword(dev, reg, val32);
0042     if (ret != 0)
0043         printk(KERN_ERR AMD8111_EDAC_MOD_STR
0044             " PCI Access Read Error at 0x%x\n", reg);
0045 
0046     return ret;
0047 }
0048 
0049 static void edac_pci_read_byte(struct pci_dev *dev, int reg, u8 *val8)
0050 {
0051     int ret;
0052 
0053     ret = pci_read_config_byte(dev, reg, val8);
0054     if (ret != 0)
0055         printk(KERN_ERR AMD8111_EDAC_MOD_STR
0056             " PCI Access Read Error at 0x%x\n", reg);
0057 }
0058 
0059 static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
0060 {
0061     int ret;
0062 
0063     ret = pci_write_config_dword(dev, reg, val32);
0064     if (ret != 0)
0065         printk(KERN_ERR AMD8111_EDAC_MOD_STR
0066             " PCI Access Write Error at 0x%x\n", reg);
0067 }
0068 
0069 static void edac_pci_write_byte(struct pci_dev *dev, int reg, u8 val8)
0070 {
0071     int ret;
0072 
0073     ret = pci_write_config_byte(dev, reg, val8);
0074     if (ret != 0)
0075         printk(KERN_ERR AMD8111_EDAC_MOD_STR
0076             " PCI Access Write Error at 0x%x\n", reg);
0077 }
0078 
0079 /*
0080  * device-specific methods for amd8111 PCI Bridge Controller
0081  *
0082  * Error Reporting and Handling for amd8111 chipset could be found
0083  * in its datasheet 3.1.2 section, P37
0084  */
0085 static void amd8111_pci_bridge_init(struct amd8111_pci_info *pci_info)
0086 {
0087     u32 val32;
0088     struct pci_dev *dev = pci_info->dev;
0089 
0090     /* First clear error detection flags on the host interface */
0091 
0092     /* Clear SSE/SMA/STA flags in the global status register*/
0093     edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
0094     if (val32 & PCI_STSCMD_CLEAR_MASK)
0095         edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
0096 
0097     /* Clear CRC and Link Fail flags in HT Link Control reg */
0098     edac_pci_read_dword(dev, REG_HT_LINK, &val32);
0099     if (val32 & HT_LINK_CLEAR_MASK)
0100         edac_pci_write_dword(dev, REG_HT_LINK, val32);
0101 
0102     /* Second clear all fault on the secondary interface */
0103 
0104     /* Clear error flags in the memory-base limit reg. */
0105     edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
0106     if (val32 & MEM_LIMIT_CLEAR_MASK)
0107         edac_pci_write_dword(dev, REG_MEM_LIM, val32);
0108 
0109     /* Clear Discard Timer Expired flag in Interrupt/Bridge Control reg */
0110     edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
0111     if (val32 & PCI_INTBRG_CTRL_CLEAR_MASK)
0112         edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
0113 
0114     /* Last enable error detections */
0115     if (edac_op_state == EDAC_OPSTATE_POLL) {
0116         /* Enable System Error reporting in global status register */
0117         edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
0118         val32 |= PCI_STSCMD_SERREN;
0119         edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
0120 
0121         /* Enable CRC Sync flood packets to HyperTransport Link */
0122         edac_pci_read_dword(dev, REG_HT_LINK, &val32);
0123         val32 |= HT_LINK_CRCFEN;
0124         edac_pci_write_dword(dev, REG_HT_LINK, val32);
0125 
0126         /* Enable SSE reporting etc in Interrupt control reg */
0127         edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
0128         val32 |= PCI_INTBRG_CTRL_POLL_MASK;
0129         edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
0130     }
0131 }
0132 
0133 static void amd8111_pci_bridge_exit(struct amd8111_pci_info *pci_info)
0134 {
0135     u32 val32;
0136     struct pci_dev *dev = pci_info->dev;
0137 
0138     if (edac_op_state == EDAC_OPSTATE_POLL) {
0139         /* Disable System Error reporting */
0140         edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
0141         val32 &= ~PCI_STSCMD_SERREN;
0142         edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
0143 
0144         /* Disable CRC flood packets */
0145         edac_pci_read_dword(dev, REG_HT_LINK, &val32);
0146         val32 &= ~HT_LINK_CRCFEN;
0147         edac_pci_write_dword(dev, REG_HT_LINK, val32);
0148 
0149         /* Disable DTSERREN/MARSP/SERREN in Interrupt Control reg */
0150         edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
0151         val32 &= ~PCI_INTBRG_CTRL_POLL_MASK;
0152         edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
0153     }
0154 }
0155 
0156 static void amd8111_pci_bridge_check(struct edac_pci_ctl_info *edac_dev)
0157 {
0158     struct amd8111_pci_info *pci_info = edac_dev->pvt_info;
0159     struct pci_dev *dev = pci_info->dev;
0160     u32 val32;
0161 
0162     /* Check out PCI Bridge Status and Command Register */
0163     edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
0164     if (val32 & PCI_STSCMD_CLEAR_MASK) {
0165         printk(KERN_INFO "Error(s) in PCI bridge status and command"
0166             "register on device %s\n", pci_info->ctl_name);
0167         printk(KERN_INFO "SSE: %d, RMA: %d, RTA: %d\n",
0168             (val32 & PCI_STSCMD_SSE) != 0,
0169             (val32 & PCI_STSCMD_RMA) != 0,
0170             (val32 & PCI_STSCMD_RTA) != 0);
0171 
0172         val32 |= PCI_STSCMD_CLEAR_MASK;
0173         edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
0174 
0175         edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
0176     }
0177 
0178     /* Check out HyperTransport Link Control Register */
0179     edac_pci_read_dword(dev, REG_HT_LINK, &val32);
0180     if (val32 & HT_LINK_LKFAIL) {
0181         printk(KERN_INFO "Error(s) in hypertransport link control"
0182             "register on device %s\n", pci_info->ctl_name);
0183         printk(KERN_INFO "LKFAIL: %d\n",
0184             (val32 & HT_LINK_LKFAIL) != 0);
0185 
0186         val32 |= HT_LINK_LKFAIL;
0187         edac_pci_write_dword(dev, REG_HT_LINK, val32);
0188 
0189         edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
0190     }
0191 
0192     /* Check out PCI Interrupt and Bridge Control Register */
0193     edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
0194     if (val32 & PCI_INTBRG_CTRL_DTSTAT) {
0195         printk(KERN_INFO "Error(s) in PCI interrupt and bridge control"
0196             "register on device %s\n", pci_info->ctl_name);
0197         printk(KERN_INFO "DTSTAT: %d\n",
0198             (val32 & PCI_INTBRG_CTRL_DTSTAT) != 0);
0199 
0200         val32 |= PCI_INTBRG_CTRL_DTSTAT;
0201         edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
0202 
0203         edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
0204     }
0205 
0206     /* Check out PCI Bridge Memory Base-Limit Register */
0207     edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
0208     if (val32 & MEM_LIMIT_CLEAR_MASK) {
0209         printk(KERN_INFO
0210             "Error(s) in mem limit register on %s device\n",
0211             pci_info->ctl_name);
0212         printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
0213             "RTA: %d, STA: %d, MDPE: %d\n",
0214             (val32 & MEM_LIMIT_DPE)  != 0,
0215             (val32 & MEM_LIMIT_RSE)  != 0,
0216             (val32 & MEM_LIMIT_RMA)  != 0,
0217             (val32 & MEM_LIMIT_RTA)  != 0,
0218             (val32 & MEM_LIMIT_STA)  != 0,
0219             (val32 & MEM_LIMIT_MDPE) != 0);
0220 
0221         val32 |= MEM_LIMIT_CLEAR_MASK;
0222         edac_pci_write_dword(dev, REG_MEM_LIM, val32);
0223 
0224         edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
0225     }
0226 }
0227 
0228 static struct resource *legacy_io_res;
0229 static int at_compat_reg_broken;
0230 #define LEGACY_NR_PORTS 1
0231 
0232 /* device-specific methods for amd8111 LPC Bridge device */
0233 static void amd8111_lpc_bridge_init(struct amd8111_dev_info *dev_info)
0234 {
0235     u8 val8;
0236     struct pci_dev *dev = dev_info->dev;
0237 
0238     /* First clear REG_AT_COMPAT[SERR, IOCHK] if necessary */
0239     legacy_io_res = request_region(REG_AT_COMPAT, LEGACY_NR_PORTS,
0240                     AMD8111_EDAC_MOD_STR);
0241     if (!legacy_io_res)
0242         printk(KERN_INFO "%s: failed to request legacy I/O region "
0243             "start %d, len %d\n", __func__,
0244             REG_AT_COMPAT, LEGACY_NR_PORTS);
0245     else {
0246         val8 = __do_inb(REG_AT_COMPAT);
0247         if (val8 == 0xff) { /* buggy port */
0248             printk(KERN_INFO "%s: port %d is buggy, not supported"
0249                 " by hardware?\n", __func__, REG_AT_COMPAT);
0250             at_compat_reg_broken = 1;
0251             release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
0252             legacy_io_res = NULL;
0253         } else {
0254             u8 out8 = 0;
0255             if (val8 & AT_COMPAT_SERR)
0256                 out8 = AT_COMPAT_CLRSERR;
0257             if (val8 & AT_COMPAT_IOCHK)
0258                 out8 |= AT_COMPAT_CLRIOCHK;
0259             if (out8 > 0)
0260                 __do_outb(out8, REG_AT_COMPAT);
0261         }
0262     }
0263 
0264     /* Second clear error flags on LPC bridge */
0265     edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
0266     if (val8 & IO_CTRL_1_CLEAR_MASK)
0267         edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
0268 }
0269 
0270 static void amd8111_lpc_bridge_exit(struct amd8111_dev_info *dev_info)
0271 {
0272     if (legacy_io_res)
0273         release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
0274 }
0275 
0276 static void amd8111_lpc_bridge_check(struct edac_device_ctl_info *edac_dev)
0277 {
0278     struct amd8111_dev_info *dev_info = edac_dev->pvt_info;
0279     struct pci_dev *dev = dev_info->dev;
0280     u8 val8;
0281 
0282     edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
0283     if (val8 & IO_CTRL_1_CLEAR_MASK) {
0284         printk(KERN_INFO
0285             "Error(s) in IO control register on %s device\n",
0286             dev_info->ctl_name);
0287         printk(KERN_INFO "LPC ERR: %d, PW2LPC: %d\n",
0288             (val8 & IO_CTRL_1_LPC_ERR) != 0,
0289             (val8 & IO_CTRL_1_PW2LPC) != 0);
0290 
0291         val8 |= IO_CTRL_1_CLEAR_MASK;
0292         edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
0293 
0294         edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
0295     }
0296 
0297     if (at_compat_reg_broken == 0) {
0298         u8 out8 = 0;
0299         val8 = __do_inb(REG_AT_COMPAT);
0300         if (val8 & AT_COMPAT_SERR)
0301             out8 = AT_COMPAT_CLRSERR;
0302         if (val8 & AT_COMPAT_IOCHK)
0303             out8 |= AT_COMPAT_CLRIOCHK;
0304         if (out8 > 0) {
0305             __do_outb(out8, REG_AT_COMPAT);
0306             edac_device_handle_ue(edac_dev, 0, 0,
0307                         edac_dev->ctl_name);
0308         }
0309     }
0310 }
0311 
0312 /* General devices represented by edac_device_ctl_info */
0313 static struct amd8111_dev_info amd8111_devices[] = {
0314     [LPC_BRIDGE] = {
0315         .err_dev = PCI_DEVICE_ID_AMD_8111_LPC,
0316         .ctl_name = "lpc",
0317         .init = amd8111_lpc_bridge_init,
0318         .exit = amd8111_lpc_bridge_exit,
0319         .check = amd8111_lpc_bridge_check,
0320     },
0321     {0},
0322 };
0323 
0324 /* PCI controllers represented by edac_pci_ctl_info */
0325 static struct amd8111_pci_info amd8111_pcis[] = {
0326     [PCI_BRIDGE] = {
0327         .err_dev = PCI_DEVICE_ID_AMD_8111_PCI,
0328         .ctl_name = "AMD8111_PCI_Controller",
0329         .init = amd8111_pci_bridge_init,
0330         .exit = amd8111_pci_bridge_exit,
0331         .check = amd8111_pci_bridge_check,
0332     },
0333     {0},
0334 };
0335 
0336 static int amd8111_dev_probe(struct pci_dev *dev,
0337                 const struct pci_device_id *id)
0338 {
0339     struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data];
0340     int ret = -ENODEV;
0341 
0342     dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
0343                     dev_info->err_dev, NULL);
0344 
0345     if (!dev_info->dev) {
0346         printk(KERN_ERR "EDAC device not found:"
0347             "vendor %x, device %x, name %s\n",
0348             PCI_VENDOR_ID_AMD, dev_info->err_dev,
0349             dev_info->ctl_name);
0350         goto err;
0351     }
0352 
0353     if (pci_enable_device(dev_info->dev)) {
0354         printk(KERN_ERR "failed to enable:"
0355             "vendor %x, device %x, name %s\n",
0356             PCI_VENDOR_ID_AMD, dev_info->err_dev,
0357             dev_info->ctl_name);
0358         goto err_dev_put;
0359     }
0360 
0361     /*
0362      * we do not allocate extra private structure for
0363      * edac_device_ctl_info, but make use of existing
0364      * one instead.
0365     */
0366     dev_info->edac_idx = edac_device_alloc_index();
0367     dev_info->edac_dev =
0368         edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1,
0369                        NULL, 0, 0,
0370                        NULL, 0, dev_info->edac_idx);
0371     if (!dev_info->edac_dev) {
0372         ret = -ENOMEM;
0373         goto err_dev_put;
0374     }
0375 
0376     dev_info->edac_dev->pvt_info = dev_info;
0377     dev_info->edac_dev->dev = &dev_info->dev->dev;
0378     dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
0379     dev_info->edac_dev->ctl_name = dev_info->ctl_name;
0380     dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);
0381 
0382     if (edac_op_state == EDAC_OPSTATE_POLL)
0383         dev_info->edac_dev->edac_check = dev_info->check;
0384 
0385     if (dev_info->init)
0386         dev_info->init(dev_info);
0387 
0388     if (edac_device_add_device(dev_info->edac_dev) > 0) {
0389         printk(KERN_ERR "failed to add edac_dev for %s\n",
0390             dev_info->ctl_name);
0391         goto err_edac_free_ctl;
0392     }
0393 
0394     printk(KERN_INFO "added one edac_dev on AMD8111 "
0395         "vendor %x, device %x, name %s\n",
0396         PCI_VENDOR_ID_AMD, dev_info->err_dev,
0397         dev_info->ctl_name);
0398 
0399     return 0;
0400 
0401 err_edac_free_ctl:
0402     edac_device_free_ctl_info(dev_info->edac_dev);
0403 err_dev_put:
0404     pci_dev_put(dev_info->dev);
0405 err:
0406     return ret;
0407 }
0408 
0409 static void amd8111_dev_remove(struct pci_dev *dev)
0410 {
0411     struct amd8111_dev_info *dev_info;
0412 
0413     for (dev_info = amd8111_devices; dev_info->err_dev; dev_info++)
0414         if (dev_info->dev->device == dev->device)
0415             break;
0416 
0417     if (!dev_info->err_dev) /* should never happen */
0418         return;
0419 
0420     if (dev_info->edac_dev) {
0421         edac_device_del_device(dev_info->edac_dev->dev);
0422         edac_device_free_ctl_info(dev_info->edac_dev);
0423     }
0424 
0425     if (dev_info->exit)
0426         dev_info->exit(dev_info);
0427 
0428     pci_dev_put(dev_info->dev);
0429 }
0430 
0431 static int amd8111_pci_probe(struct pci_dev *dev,
0432                 const struct pci_device_id *id)
0433 {
0434     struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data];
0435     int ret = -ENODEV;
0436 
0437     pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
0438                     pci_info->err_dev, NULL);
0439 
0440     if (!pci_info->dev) {
0441         printk(KERN_ERR "EDAC device not found:"
0442             "vendor %x, device %x, name %s\n",
0443             PCI_VENDOR_ID_AMD, pci_info->err_dev,
0444             pci_info->ctl_name);
0445         goto err;
0446     }
0447 
0448     if (pci_enable_device(pci_info->dev)) {
0449         printk(KERN_ERR "failed to enable:"
0450             "vendor %x, device %x, name %s\n",
0451             PCI_VENDOR_ID_AMD, pci_info->err_dev,
0452             pci_info->ctl_name);
0453         goto err_dev_put;
0454     }
0455 
0456     /*
0457      * we do not allocate extra private structure for
0458      * edac_pci_ctl_info, but make use of existing
0459      * one instead.
0460     */
0461     pci_info->edac_idx = edac_pci_alloc_index();
0462     pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name);
0463     if (!pci_info->edac_dev) {
0464         ret = -ENOMEM;
0465         goto err_dev_put;
0466     }
0467 
0468     pci_info->edac_dev->pvt_info = pci_info;
0469     pci_info->edac_dev->dev = &pci_info->dev->dev;
0470     pci_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
0471     pci_info->edac_dev->ctl_name = pci_info->ctl_name;
0472     pci_info->edac_dev->dev_name = dev_name(&pci_info->dev->dev);
0473 
0474     if (edac_op_state == EDAC_OPSTATE_POLL)
0475         pci_info->edac_dev->edac_check = pci_info->check;
0476 
0477     if (pci_info->init)
0478         pci_info->init(pci_info);
0479 
0480     if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) {
0481         printk(KERN_ERR "failed to add edac_pci for %s\n",
0482             pci_info->ctl_name);
0483         goto err_edac_free_ctl;
0484     }
0485 
0486     printk(KERN_INFO "added one edac_pci on AMD8111 "
0487         "vendor %x, device %x, name %s\n",
0488         PCI_VENDOR_ID_AMD, pci_info->err_dev,
0489         pci_info->ctl_name);
0490 
0491     return 0;
0492 
0493 err_edac_free_ctl:
0494     edac_pci_free_ctl_info(pci_info->edac_dev);
0495 err_dev_put:
0496     pci_dev_put(pci_info->dev);
0497 err:
0498     return ret;
0499 }
0500 
0501 static void amd8111_pci_remove(struct pci_dev *dev)
0502 {
0503     struct amd8111_pci_info *pci_info;
0504 
0505     for (pci_info = amd8111_pcis; pci_info->err_dev; pci_info++)
0506         if (pci_info->dev->device == dev->device)
0507             break;
0508 
0509     if (!pci_info->err_dev) /* should never happen */
0510         return;
0511 
0512     if (pci_info->edac_dev) {
0513         edac_pci_del_device(pci_info->edac_dev->dev);
0514         edac_pci_free_ctl_info(pci_info->edac_dev);
0515     }
0516 
0517     if (pci_info->exit)
0518         pci_info->exit(pci_info);
0519 
0520     pci_dev_put(pci_info->dev);
0521 }
0522 
0523 /* PCI Device ID talbe for general EDAC device */
0524 static const struct pci_device_id amd8111_edac_dev_tbl[] = {
0525     {
0526     PCI_VEND_DEV(AMD, 8111_LPC),
0527     .subvendor = PCI_ANY_ID,
0528     .subdevice = PCI_ANY_ID,
0529     .class = 0,
0530     .class_mask = 0,
0531     .driver_data = LPC_BRIDGE,
0532     },
0533     {
0534     0,
0535     }           /* table is NULL-terminated */
0536 };
0537 MODULE_DEVICE_TABLE(pci, amd8111_edac_dev_tbl);
0538 
0539 static struct pci_driver amd8111_edac_dev_driver = {
0540     .name = "AMD8111_EDAC_DEV",
0541     .probe = amd8111_dev_probe,
0542     .remove = amd8111_dev_remove,
0543     .id_table = amd8111_edac_dev_tbl,
0544 };
0545 
0546 /* PCI Device ID table for EDAC PCI controller */
0547 static const struct pci_device_id amd8111_edac_pci_tbl[] = {
0548     {
0549     PCI_VEND_DEV(AMD, 8111_PCI),
0550     .subvendor = PCI_ANY_ID,
0551     .subdevice = PCI_ANY_ID,
0552     .class = 0,
0553     .class_mask = 0,
0554     .driver_data = PCI_BRIDGE,
0555     },
0556     {
0557     0,
0558     }           /* table is NULL-terminated */
0559 };
0560 MODULE_DEVICE_TABLE(pci, amd8111_edac_pci_tbl);
0561 
0562 static struct pci_driver amd8111_edac_pci_driver = {
0563     .name = "AMD8111_EDAC_PCI",
0564     .probe = amd8111_pci_probe,
0565     .remove = amd8111_pci_remove,
0566     .id_table = amd8111_edac_pci_tbl,
0567 };
0568 
0569 static int __init amd8111_edac_init(void)
0570 {
0571     int val;
0572 
0573     printk(KERN_INFO "AMD8111 EDAC driver " AMD8111_EDAC_REVISION "\n");
0574     printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
0575 
0576     /* Only POLL mode supported so far */
0577     edac_op_state = EDAC_OPSTATE_POLL;
0578 
0579     val = pci_register_driver(&amd8111_edac_dev_driver);
0580     val |= pci_register_driver(&amd8111_edac_pci_driver);
0581 
0582     return val;
0583 }
0584 
0585 static void __exit amd8111_edac_exit(void)
0586 {
0587     pci_unregister_driver(&amd8111_edac_pci_driver);
0588     pci_unregister_driver(&amd8111_edac_dev_driver);
0589 }
0590 
0591 
0592 module_init(amd8111_edac_init);
0593 module_exit(amd8111_edac_exit);
0594 
0595 MODULE_LICENSE("GPL");
0596 MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>\n");
0597 MODULE_DESCRIPTION("AMD8111 HyperTransport I/O Hub EDAC kernel module");