linux/drivers/edac/amd8111_edac.c
<<
>>
Prefs
   1/*
   2 * amd8111_edac.c, AMD8111 Hyper Transport chip EDAC kernel module
   3 *
   4 * Copyright (c) 2008 Wind River Systems, Inc.
   5 *
   6 * Authors:     Cao Qingtao <qingtao.cao@windriver.com>
   7 *              Benjamin Walsh <benjamin.walsh@windriver.com>
   8 *              Hu Yongqi <yongqi.hu@windriver.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17 * See the GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23
  24#include <linux/module.h>
  25#include <linux/init.h>
  26#include <linux/interrupt.h>
  27#include <linux/bitops.h>
  28#include <linux/edac.h>
  29#include <linux/pci_ids.h>
  30#include <asm/io.h>
  31
  32#include "edac_module.h"
  33#include "amd8111_edac.h"
  34
  35#define AMD8111_EDAC_REVISION   " Ver: 1.0.0"
  36#define AMD8111_EDAC_MOD_STR    "amd8111_edac"
  37
  38#define PCI_DEVICE_ID_AMD_8111_PCI      0x7460
  39
  40enum amd8111_edac_devs {
  41        LPC_BRIDGE = 0,
  42};
  43
  44enum amd8111_edac_pcis {
  45        PCI_BRIDGE = 0,
  46};
  47
  48/* Wrapper functions for accessing PCI configuration space */
  49static int edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
  50{
  51        int ret;
  52
  53        ret = pci_read_config_dword(dev, reg, val32);
  54        if (ret != 0)
  55                printk(KERN_ERR AMD8111_EDAC_MOD_STR
  56                        " PCI Access Read Error at 0x%x\n", reg);
  57
  58        return ret;
  59}
  60
  61static void edac_pci_read_byte(struct pci_dev *dev, int reg, u8 *val8)
  62{
  63        int ret;
  64
  65        ret = pci_read_config_byte(dev, reg, val8);
  66        if (ret != 0)
  67                printk(KERN_ERR AMD8111_EDAC_MOD_STR
  68                        " PCI Access Read Error at 0x%x\n", reg);
  69}
  70
  71static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
  72{
  73        int ret;
  74
  75        ret = pci_write_config_dword(dev, reg, val32);
  76        if (ret != 0)
  77                printk(KERN_ERR AMD8111_EDAC_MOD_STR
  78                        " PCI Access Write Error at 0x%x\n", reg);
  79}
  80
  81static void edac_pci_write_byte(struct pci_dev *dev, int reg, u8 val8)
  82{
  83        int ret;
  84
  85        ret = pci_write_config_byte(dev, reg, val8);
  86        if (ret != 0)
  87                printk(KERN_ERR AMD8111_EDAC_MOD_STR
  88                        " PCI Access Write Error at 0x%x\n", reg);
  89}
  90
  91/*
  92 * device-specific methods for amd8111 PCI Bridge Controller
  93 *
  94 * Error Reporting and Handling for amd8111 chipset could be found
  95 * in its datasheet 3.1.2 section, P37
  96 */
  97static void amd8111_pci_bridge_init(struct amd8111_pci_info *pci_info)
  98{
  99        u32 val32;
 100        struct pci_dev *dev = pci_info->dev;
 101
 102        /* First clear error detection flags on the host interface */
 103
 104        /* Clear SSE/SMA/STA flags in the global status register*/
 105        edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
 106        if (val32 & PCI_STSCMD_CLEAR_MASK)
 107                edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
 108
 109        /* Clear CRC and Link Fail flags in HT Link Control reg */
 110        edac_pci_read_dword(dev, REG_HT_LINK, &val32);
 111        if (val32 & HT_LINK_CLEAR_MASK)
 112                edac_pci_write_dword(dev, REG_HT_LINK, val32);
 113
 114        /* Second clear all fault on the secondary interface */
 115
 116        /* Clear error flags in the memory-base limit reg. */
 117        edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
 118        if (val32 & MEM_LIMIT_CLEAR_MASK)
 119                edac_pci_write_dword(dev, REG_MEM_LIM, val32);
 120
 121        /* Clear Discard Timer Expired flag in Interrupt/Bridge Control reg */
 122        edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
 123        if (val32 & PCI_INTBRG_CTRL_CLEAR_MASK)
 124                edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
 125
 126        /* Last enable error detections */
 127        if (edac_op_state == EDAC_OPSTATE_POLL) {
 128                /* Enable System Error reporting in global status register */
 129                edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
 130                val32 |= PCI_STSCMD_SERREN;
 131                edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
 132
 133                /* Enable CRC Sync flood packets to HyperTransport Link */
 134                edac_pci_read_dword(dev, REG_HT_LINK, &val32);
 135                val32 |= HT_LINK_CRCFEN;
 136                edac_pci_write_dword(dev, REG_HT_LINK, val32);
 137
 138                /* Enable SSE reporting etc in Interrupt control reg */
 139                edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
 140                val32 |= PCI_INTBRG_CTRL_POLL_MASK;
 141                edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
 142        }
 143}
 144
 145static void amd8111_pci_bridge_exit(struct amd8111_pci_info *pci_info)
 146{
 147        u32 val32;
 148        struct pci_dev *dev = pci_info->dev;
 149
 150        if (edac_op_state == EDAC_OPSTATE_POLL) {
 151                /* Disable System Error reporting */
 152                edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
 153                val32 &= ~PCI_STSCMD_SERREN;
 154                edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
 155
 156                /* Disable CRC flood packets */
 157                edac_pci_read_dword(dev, REG_HT_LINK, &val32);
 158                val32 &= ~HT_LINK_CRCFEN;
 159                edac_pci_write_dword(dev, REG_HT_LINK, val32);
 160
 161                /* Disable DTSERREN/MARSP/SERREN in Interrupt Control reg */
 162                edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
 163                val32 &= ~PCI_INTBRG_CTRL_POLL_MASK;
 164                edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
 165        }
 166}
 167
 168static void amd8111_pci_bridge_check(struct edac_pci_ctl_info *edac_dev)
 169{
 170        struct amd8111_pci_info *pci_info = edac_dev->pvt_info;
 171        struct pci_dev *dev = pci_info->dev;
 172        u32 val32;
 173
 174        /* Check out PCI Bridge Status and Command Register */
 175        edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
 176        if (val32 & PCI_STSCMD_CLEAR_MASK) {
 177                printk(KERN_INFO "Error(s) in PCI bridge status and command"
 178                        "register on device %s\n", pci_info->ctl_name);
 179                printk(KERN_INFO "SSE: %d, RMA: %d, RTA: %d\n",
 180                        (val32 & PCI_STSCMD_SSE) != 0,
 181                        (val32 & PCI_STSCMD_RMA) != 0,
 182                        (val32 & PCI_STSCMD_RTA) != 0);
 183
 184                val32 |= PCI_STSCMD_CLEAR_MASK;
 185                edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
 186
 187                edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
 188        }
 189
 190        /* Check out HyperTransport Link Control Register */
 191        edac_pci_read_dword(dev, REG_HT_LINK, &val32);
 192        if (val32 & HT_LINK_LKFAIL) {
 193                printk(KERN_INFO "Error(s) in hypertransport link control"
 194                        "register on device %s\n", pci_info->ctl_name);
 195                printk(KERN_INFO "LKFAIL: %d\n",
 196                        (val32 & HT_LINK_LKFAIL) != 0);
 197
 198                val32 |= HT_LINK_LKFAIL;
 199                edac_pci_write_dword(dev, REG_HT_LINK, val32);
 200
 201                edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
 202        }
 203
 204        /* Check out PCI Interrupt and Bridge Control Register */
 205        edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
 206        if (val32 & PCI_INTBRG_CTRL_DTSTAT) {
 207                printk(KERN_INFO "Error(s) in PCI interrupt and bridge control"
 208                        "register on device %s\n", pci_info->ctl_name);
 209                printk(KERN_INFO "DTSTAT: %d\n",
 210                        (val32 & PCI_INTBRG_CTRL_DTSTAT) != 0);
 211
 212                val32 |= PCI_INTBRG_CTRL_DTSTAT;
 213                edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
 214
 215                edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
 216        }
 217
 218        /* Check out PCI Bridge Memory Base-Limit Register */
 219        edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
 220        if (val32 & MEM_LIMIT_CLEAR_MASK) {
 221                printk(KERN_INFO
 222                        "Error(s) in mem limit register on %s device\n",
 223                        pci_info->ctl_name);
 224                printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
 225                        "RTA: %d, STA: %d, MDPE: %d\n",
 226                        (val32 & MEM_LIMIT_DPE)  != 0,
 227                        (val32 & MEM_LIMIT_RSE)  != 0,
 228                        (val32 & MEM_LIMIT_RMA)  != 0,
 229                        (val32 & MEM_LIMIT_RTA)  != 0,
 230                        (val32 & MEM_LIMIT_STA)  != 0,
 231                        (val32 & MEM_LIMIT_MDPE) != 0);
 232
 233                val32 |= MEM_LIMIT_CLEAR_MASK;
 234                edac_pci_write_dword(dev, REG_MEM_LIM, val32);
 235
 236                edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
 237        }
 238}
 239
 240static struct resource *legacy_io_res;
 241static int at_compat_reg_broken;
 242#define LEGACY_NR_PORTS 1
 243
 244/* device-specific methods for amd8111 LPC Bridge device */
 245static void amd8111_lpc_bridge_init(struct amd8111_dev_info *dev_info)
 246{
 247        u8 val8;
 248        struct pci_dev *dev = dev_info->dev;
 249
 250        /* First clear REG_AT_COMPAT[SERR, IOCHK] if necessary */
 251        legacy_io_res = request_region(REG_AT_COMPAT, LEGACY_NR_PORTS,
 252                                        AMD8111_EDAC_MOD_STR);
 253        if (!legacy_io_res)
 254                printk(KERN_INFO "%s: failed to request legacy I/O region "
 255                        "start %d, len %d\n", __func__,
 256                        REG_AT_COMPAT, LEGACY_NR_PORTS);
 257        else {
 258                val8 = __do_inb(REG_AT_COMPAT);
 259                if (val8 == 0xff) { /* buggy port */
 260                        printk(KERN_INFO "%s: port %d is buggy, not supported"
 261                                " by hardware?\n", __func__, REG_AT_COMPAT);
 262                        at_compat_reg_broken = 1;
 263                        release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
 264                        legacy_io_res = NULL;
 265                } else {
 266                        u8 out8 = 0;
 267                        if (val8 & AT_COMPAT_SERR)
 268                                out8 = AT_COMPAT_CLRSERR;
 269                        if (val8 & AT_COMPAT_IOCHK)
 270                                out8 |= AT_COMPAT_CLRIOCHK;
 271                        if (out8 > 0)
 272                                __do_outb(out8, REG_AT_COMPAT);
 273                }
 274        }
 275
 276        /* Second clear error flags on LPC bridge */
 277        edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
 278        if (val8 & IO_CTRL_1_CLEAR_MASK)
 279                edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
 280}
 281
 282static void amd8111_lpc_bridge_exit(struct amd8111_dev_info *dev_info)
 283{
 284        if (legacy_io_res)
 285                release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
 286}
 287
 288static void amd8111_lpc_bridge_check(struct edac_device_ctl_info *edac_dev)
 289{
 290        struct amd8111_dev_info *dev_info = edac_dev->pvt_info;
 291        struct pci_dev *dev = dev_info->dev;
 292        u8 val8;
 293
 294        edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
 295        if (val8 & IO_CTRL_1_CLEAR_MASK) {
 296                printk(KERN_INFO
 297                        "Error(s) in IO control register on %s device\n",
 298                        dev_info->ctl_name);
 299                printk(KERN_INFO "LPC ERR: %d, PW2LPC: %d\n",
 300                        (val8 & IO_CTRL_1_LPC_ERR) != 0,
 301                        (val8 & IO_CTRL_1_PW2LPC) != 0);
 302
 303                val8 |= IO_CTRL_1_CLEAR_MASK;
 304                edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
 305
 306                edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
 307        }
 308
 309        if (at_compat_reg_broken == 0) {
 310                u8 out8 = 0;
 311                val8 = __do_inb(REG_AT_COMPAT);
 312                if (val8 & AT_COMPAT_SERR)
 313                        out8 = AT_COMPAT_CLRSERR;
 314                if (val8 & AT_COMPAT_IOCHK)
 315                        out8 |= AT_COMPAT_CLRIOCHK;
 316                if (out8 > 0) {
 317                        __do_outb(out8, REG_AT_COMPAT);
 318                        edac_device_handle_ue(edac_dev, 0, 0,
 319                                                edac_dev->ctl_name);
 320                }
 321        }
 322}
 323
 324/* General devices represented by edac_device_ctl_info */
 325static struct amd8111_dev_info amd8111_devices[] = {
 326        [LPC_BRIDGE] = {
 327                .err_dev = PCI_DEVICE_ID_AMD_8111_LPC,
 328                .ctl_name = "lpc",
 329                .init = amd8111_lpc_bridge_init,
 330                .exit = amd8111_lpc_bridge_exit,
 331                .check = amd8111_lpc_bridge_check,
 332        },
 333        {0},
 334};
 335
 336/* PCI controllers represented by edac_pci_ctl_info */
 337static struct amd8111_pci_info amd8111_pcis[] = {
 338        [PCI_BRIDGE] = {
 339                .err_dev = PCI_DEVICE_ID_AMD_8111_PCI,
 340                .ctl_name = "AMD8111_PCI_Controller",
 341                .init = amd8111_pci_bridge_init,
 342                .exit = amd8111_pci_bridge_exit,
 343                .check = amd8111_pci_bridge_check,
 344        },
 345        {0},
 346};
 347
 348static int amd8111_dev_probe(struct pci_dev *dev,
 349                                const struct pci_device_id *id)
 350{
 351        struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data];
 352        int ret = -ENODEV;
 353
 354        dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
 355                                        dev_info->err_dev, NULL);
 356
 357        if (!dev_info->dev) {
 358                printk(KERN_ERR "EDAC device not found:"
 359                        "vendor %x, device %x, name %s\n",
 360                        PCI_VENDOR_ID_AMD, dev_info->err_dev,
 361                        dev_info->ctl_name);
 362                goto err;
 363        }
 364
 365        if (pci_enable_device(dev_info->dev)) {
 366                printk(KERN_ERR "failed to enable:"
 367                        "vendor %x, device %x, name %s\n",
 368                        PCI_VENDOR_ID_AMD, dev_info->err_dev,
 369                        dev_info->ctl_name);
 370                goto err_dev_put;
 371        }
 372
 373        /*
 374         * we do not allocate extra private structure for
 375         * edac_device_ctl_info, but make use of existing
 376         * one instead.
 377        */
 378        dev_info->edac_idx = edac_device_alloc_index();
 379        dev_info->edac_dev =
 380                edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1,
 381                                           NULL, 0, 0,
 382                                           NULL, 0, dev_info->edac_idx);
 383        if (!dev_info->edac_dev) {
 384                ret = -ENOMEM;
 385                goto err_dev_put;
 386        }
 387
 388        dev_info->edac_dev->pvt_info = dev_info;
 389        dev_info->edac_dev->dev = &dev_info->dev->dev;
 390        dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
 391        dev_info->edac_dev->ctl_name = dev_info->ctl_name;
 392        dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);
 393
 394        if (edac_op_state == EDAC_OPSTATE_POLL)
 395                dev_info->edac_dev->edac_check = dev_info->check;
 396
 397        if (dev_info->init)
 398                dev_info->init(dev_info);
 399
 400        if (edac_device_add_device(dev_info->edac_dev) > 0) {
 401                printk(KERN_ERR "failed to add edac_dev for %s\n",
 402                        dev_info->ctl_name);
 403                goto err_edac_free_ctl;
 404        }
 405
 406        printk(KERN_INFO "added one edac_dev on AMD8111 "
 407                "vendor %x, device %x, name %s\n",
 408                PCI_VENDOR_ID_AMD, dev_info->err_dev,
 409                dev_info->ctl_name);
 410
 411        return 0;
 412
 413err_edac_free_ctl:
 414        edac_device_free_ctl_info(dev_info->edac_dev);
 415err_dev_put:
 416        pci_dev_put(dev_info->dev);
 417err:
 418        return ret;
 419}
 420
 421static void amd8111_dev_remove(struct pci_dev *dev)
 422{
 423        struct amd8111_dev_info *dev_info;
 424
 425        for (dev_info = amd8111_devices; dev_info->err_dev; dev_info++)
 426                if (dev_info->dev->device == dev->device)
 427                        break;
 428
 429        if (!dev_info->err_dev) /* should never happen */
 430                return;
 431
 432        if (dev_info->edac_dev) {
 433                edac_device_del_device(dev_info->edac_dev->dev);
 434                edac_device_free_ctl_info(dev_info->edac_dev);
 435        }
 436
 437        if (dev_info->exit)
 438                dev_info->exit(dev_info);
 439
 440        pci_dev_put(dev_info->dev);
 441}
 442
 443static int amd8111_pci_probe(struct pci_dev *dev,
 444                                const struct pci_device_id *id)
 445{
 446        struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data];
 447        int ret = -ENODEV;
 448
 449        pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
 450                                        pci_info->err_dev, NULL);
 451
 452        if (!pci_info->dev) {
 453                printk(KERN_ERR "EDAC device not found:"
 454                        "vendor %x, device %x, name %s\n",
 455                        PCI_VENDOR_ID_AMD, pci_info->err_dev,
 456                        pci_info->ctl_name);
 457                goto err;
 458        }
 459
 460        if (pci_enable_device(pci_info->dev)) {
 461                printk(KERN_ERR "failed to enable:"
 462                        "vendor %x, device %x, name %s\n",
 463                        PCI_VENDOR_ID_AMD, pci_info->err_dev,
 464                        pci_info->ctl_name);
 465                goto err_dev_put;
 466        }
 467
 468        /*
 469         * we do not allocate extra private structure for
 470         * edac_pci_ctl_info, but make use of existing
 471         * one instead.
 472        */
 473        pci_info->edac_idx = edac_pci_alloc_index();
 474        pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name);
 475        if (!pci_info->edac_dev) {
 476                ret = -ENOMEM;
 477                goto err_dev_put;
 478        }
 479
 480        pci_info->edac_dev->pvt_info = pci_info;
 481        pci_info->edac_dev->dev = &pci_info->dev->dev;
 482        pci_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
 483        pci_info->edac_dev->ctl_name = pci_info->ctl_name;
 484        pci_info->edac_dev->dev_name = dev_name(&pci_info->dev->dev);
 485
 486        if (edac_op_state == EDAC_OPSTATE_POLL)
 487                pci_info->edac_dev->edac_check = pci_info->check;
 488
 489        if (pci_info->init)
 490                pci_info->init(pci_info);
 491
 492        if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) {
 493                printk(KERN_ERR "failed to add edac_pci for %s\n",
 494                        pci_info->ctl_name);
 495                goto err_edac_free_ctl;
 496        }
 497
 498        printk(KERN_INFO "added one edac_pci on AMD8111 "
 499                "vendor %x, device %x, name %s\n",
 500                PCI_VENDOR_ID_AMD, pci_info->err_dev,
 501                pci_info->ctl_name);
 502
 503        return 0;
 504
 505err_edac_free_ctl:
 506        edac_pci_free_ctl_info(pci_info->edac_dev);
 507err_dev_put:
 508        pci_dev_put(pci_info->dev);
 509err:
 510        return ret;
 511}
 512
 513static void amd8111_pci_remove(struct pci_dev *dev)
 514{
 515        struct amd8111_pci_info *pci_info;
 516
 517        for (pci_info = amd8111_pcis; pci_info->err_dev; pci_info++)
 518                if (pci_info->dev->device == dev->device)
 519                        break;
 520
 521        if (!pci_info->err_dev) /* should never happen */
 522                return;
 523
 524        if (pci_info->edac_dev) {
 525                edac_pci_del_device(pci_info->edac_dev->dev);
 526                edac_pci_free_ctl_info(pci_info->edac_dev);
 527        }
 528
 529        if (pci_info->exit)
 530                pci_info->exit(pci_info);
 531
 532        pci_dev_put(pci_info->dev);
 533}
 534
 535/* PCI Device ID talbe for general EDAC device */
 536static const struct pci_device_id amd8111_edac_dev_tbl[] = {
 537        {
 538        PCI_VEND_DEV(AMD, 8111_LPC),
 539        .subvendor = PCI_ANY_ID,
 540        .subdevice = PCI_ANY_ID,
 541        .class = 0,
 542        .class_mask = 0,
 543        .driver_data = LPC_BRIDGE,
 544        },
 545        {
 546        0,
 547        }                       /* table is NULL-terminated */
 548};
 549MODULE_DEVICE_TABLE(pci, amd8111_edac_dev_tbl);
 550
 551static struct pci_driver amd8111_edac_dev_driver = {
 552        .name = "AMD8111_EDAC_DEV",
 553        .probe = amd8111_dev_probe,
 554        .remove = amd8111_dev_remove,
 555        .id_table = amd8111_edac_dev_tbl,
 556};
 557
 558/* PCI Device ID table for EDAC PCI controller */
 559static const struct pci_device_id amd8111_edac_pci_tbl[] = {
 560        {
 561        PCI_VEND_DEV(AMD, 8111_PCI),
 562        .subvendor = PCI_ANY_ID,
 563        .subdevice = PCI_ANY_ID,
 564        .class = 0,
 565        .class_mask = 0,
 566        .driver_data = PCI_BRIDGE,
 567        },
 568        {
 569        0,
 570        }                       /* table is NULL-terminated */
 571};
 572MODULE_DEVICE_TABLE(pci, amd8111_edac_pci_tbl);
 573
 574static struct pci_driver amd8111_edac_pci_driver = {
 575        .name = "AMD8111_EDAC_PCI",
 576        .probe = amd8111_pci_probe,
 577        .remove = amd8111_pci_remove,
 578        .id_table = amd8111_edac_pci_tbl,
 579};
 580
 581static int __init amd8111_edac_init(void)
 582{
 583        int val;
 584
 585        printk(KERN_INFO "AMD8111 EDAC driver " AMD8111_EDAC_REVISION "\n");
 586        printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
 587
 588        /* Only POLL mode supported so far */
 589        edac_op_state = EDAC_OPSTATE_POLL;
 590
 591        val = pci_register_driver(&amd8111_edac_dev_driver);
 592        val |= pci_register_driver(&amd8111_edac_pci_driver);
 593
 594        return val;
 595}
 596
 597static void __exit amd8111_edac_exit(void)
 598{
 599        pci_unregister_driver(&amd8111_edac_pci_driver);
 600        pci_unregister_driver(&amd8111_edac_dev_driver);
 601}
 602
 603
 604module_init(amd8111_edac_init);
 605module_exit(amd8111_edac_exit);
 606
 607MODULE_LICENSE("GPL");
 608MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>\n");
 609MODULE_DESCRIPTION("AMD8111 HyperTransport I/O Hub EDAC kernel module");
 610