linux/drivers/edac/ie31200_edac.c
<<
>>
Prefs
   1/*
   2 * Intel E3-1200
   3 * Copyright (C) 2014 Jason Baron <jbaron@akamai.com>
   4 *
   5 * Support for the E3-1200 processor family. Heavily based on previous
   6 * Intel EDAC drivers.
   7 *
   8 * Since the DRAM controller is on the cpu chip, we can use its PCI device
   9 * id to identify these processors.
  10 *
  11 * PCI DRAM controller device ids (Taken from The PCI ID Repository - http://pci-ids.ucw.cz/)
  12 *
  13 * 0108: Xeon E3-1200 Processor Family DRAM Controller
  14 * 010c: Xeon E3-1200/2nd Generation Core Processor Family DRAM Controller
  15 * 0150: Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
  16 * 0158: Xeon E3-1200 v2/Ivy Bridge DRAM Controller
  17 * 015c: Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
  18 * 0c04: Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller
  19 * 0c08: Xeon E3-1200 v3 Processor DRAM Controller
  20 * 1918: Xeon E3-1200 v5 Skylake Host Bridge/DRAM Registers
  21 * 5918: Xeon E3-1200 Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers
  22 *
  23 * Based on Intel specification:
  24 * http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xeon-e3-1200v3-vol-2-datasheet.pdf
  25 * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e3-1200-family-vol-2-datasheet.html
  26 * http://www.intel.com/content/www/us/en/processors/core/7th-gen-core-family-mobile-h-processor-lines-datasheet-vol-2.html
  27 *
  28 * According to the above datasheet (p.16):
  29 * "
  30 * 6. Software must not access B0/D0/F0 32-bit memory-mapped registers with
  31 * requests that cross a DW boundary.
  32 * "
  33 *
  34 * Thus, we make use of the explicit: lo_hi_readq(), which breaks the readq into
  35 * 2 readl() calls. This restriction may be lifted in subsequent chip releases,
  36 * but lo_hi_readq() ensures that we are safe across all e3-1200 processors.
  37 */
  38
  39#include <linux/module.h>
  40#include <linux/init.h>
  41#include <linux/pci.h>
  42#include <linux/pci_ids.h>
  43#include <linux/edac.h>
  44
  45#include <linux/io-64-nonatomic-lo-hi.h>
  46#include "edac_module.h"
  47
  48#define EDAC_MOD_STR "ie31200_edac"
  49
  50#define ie31200_printk(level, fmt, arg...) \
  51        edac_printk(level, "ie31200", fmt, ##arg)
  52
  53#define PCI_DEVICE_ID_INTEL_IE31200_HB_1 0x0108
  54#define PCI_DEVICE_ID_INTEL_IE31200_HB_2 0x010c
  55#define PCI_DEVICE_ID_INTEL_IE31200_HB_3 0x0150
  56#define PCI_DEVICE_ID_INTEL_IE31200_HB_4 0x0158
  57#define PCI_DEVICE_ID_INTEL_IE31200_HB_5 0x015c
  58#define PCI_DEVICE_ID_INTEL_IE31200_HB_6 0x0c04
  59#define PCI_DEVICE_ID_INTEL_IE31200_HB_7 0x0c08
  60#define PCI_DEVICE_ID_INTEL_IE31200_HB_8 0x1918
  61#define PCI_DEVICE_ID_INTEL_IE31200_HB_9 0x5918
  62
  63#define IE31200_DIMMS                   4
  64#define IE31200_RANKS                   8
  65#define IE31200_RANKS_PER_CHANNEL       4
  66#define IE31200_DIMMS_PER_CHANNEL       2
  67#define IE31200_CHANNELS                2
  68
  69/* Intel IE31200 register addresses - device 0 function 0 - DRAM Controller */
  70#define IE31200_MCHBAR_LOW              0x48
  71#define IE31200_MCHBAR_HIGH             0x4c
  72#define IE31200_MCHBAR_MASK             GENMASK_ULL(38, 15)
  73#define IE31200_MMR_WINDOW_SIZE         BIT(15)
  74
  75/*
  76 * Error Status Register (16b)
  77 *
  78 * 15    reserved
  79 * 14    Isochronous TBWRR Run Behind FIFO Full
  80 *       (ITCV)
  81 * 13    Isochronous TBWRR Run Behind FIFO Put
  82 *       (ITSTV)
  83 * 12    reserved
  84 * 11    MCH Thermal Sensor Event
  85 *       for SMI/SCI/SERR (GTSE)
  86 * 10    reserved
  87 *  9    LOCK to non-DRAM Memory Flag (LCKF)
  88 *  8    reserved
  89 *  7    DRAM Throttle Flag (DTF)
  90 *  6:2  reserved
  91 *  1    Multi-bit DRAM ECC Error Flag (DMERR)
  92 *  0    Single-bit DRAM ECC Error Flag (DSERR)
  93 */
  94#define IE31200_ERRSTS                  0xc8
  95#define IE31200_ERRSTS_UE               BIT(1)
  96#define IE31200_ERRSTS_CE               BIT(0)
  97#define IE31200_ERRSTS_BITS             (IE31200_ERRSTS_UE | IE31200_ERRSTS_CE)
  98
  99/*
 100 * Channel 0 ECC Error Log (64b)
 101 *
 102 * 63:48 Error Column Address (ERRCOL)
 103 * 47:32 Error Row Address (ERRROW)
 104 * 31:29 Error Bank Address (ERRBANK)
 105 * 28:27 Error Rank Address (ERRRANK)
 106 * 26:24 reserved
 107 * 23:16 Error Syndrome (ERRSYND)
 108 * 15: 2 reserved
 109 *    1  Multiple Bit Error Status (MERRSTS)
 110 *    0  Correctable Error Status (CERRSTS)
 111 */
 112
 113#define IE31200_C0ECCERRLOG                     0x40c8
 114#define IE31200_C1ECCERRLOG                     0x44c8
 115#define IE31200_C0ECCERRLOG_SKL                 0x4048
 116#define IE31200_C1ECCERRLOG_SKL                 0x4448
 117#define IE31200_ECCERRLOG_CE                    BIT(0)
 118#define IE31200_ECCERRLOG_UE                    BIT(1)
 119#define IE31200_ECCERRLOG_RANK_BITS             GENMASK_ULL(28, 27)
 120#define IE31200_ECCERRLOG_RANK_SHIFT            27
 121#define IE31200_ECCERRLOG_SYNDROME_BITS         GENMASK_ULL(23, 16)
 122#define IE31200_ECCERRLOG_SYNDROME_SHIFT        16
 123
 124#define IE31200_ECCERRLOG_SYNDROME(log)            \
 125        ((log & IE31200_ECCERRLOG_SYNDROME_BITS) >> \
 126         IE31200_ECCERRLOG_SYNDROME_SHIFT)
 127
 128#define IE31200_CAPID0                  0xe4
 129#define IE31200_CAPID0_PDCD             BIT(4)
 130#define IE31200_CAPID0_DDPCD            BIT(6)
 131#define IE31200_CAPID0_ECC              BIT(1)
 132
 133#define IE31200_MAD_DIMM_0_OFFSET               0x5004
 134#define IE31200_MAD_DIMM_0_OFFSET_SKL           0x500C
 135#define IE31200_MAD_DIMM_SIZE                   GENMASK_ULL(7, 0)
 136#define IE31200_MAD_DIMM_A_RANK                 BIT(17)
 137#define IE31200_MAD_DIMM_A_RANK_SHIFT           17
 138#define IE31200_MAD_DIMM_A_RANK_SKL             BIT(10)
 139#define IE31200_MAD_DIMM_A_RANK_SKL_SHIFT       10
 140#define IE31200_MAD_DIMM_A_WIDTH                BIT(19)
 141#define IE31200_MAD_DIMM_A_WIDTH_SHIFT          19
 142#define IE31200_MAD_DIMM_A_WIDTH_SKL            GENMASK_ULL(9, 8)
 143#define IE31200_MAD_DIMM_A_WIDTH_SKL_SHIFT      8
 144
 145/* Skylake reports 1GB increments, everything else is 256MB */
 146#define IE31200_PAGES(n, skl)   \
 147        (n << (28 + (2 * skl) - PAGE_SHIFT))
 148
 149static int nr_channels;
 150
 151struct ie31200_priv {
 152        void __iomem *window;
 153        void __iomem *c0errlog;
 154        void __iomem *c1errlog;
 155};
 156
 157enum ie31200_chips {
 158        IE31200 = 0,
 159};
 160
 161struct ie31200_dev_info {
 162        const char *ctl_name;
 163};
 164
 165struct ie31200_error_info {
 166        u16 errsts;
 167        u16 errsts2;
 168        u64 eccerrlog[IE31200_CHANNELS];
 169};
 170
 171static const struct ie31200_dev_info ie31200_devs[] = {
 172        [IE31200] = {
 173                .ctl_name = "IE31200"
 174        },
 175};
 176
 177struct dimm_data {
 178        u8 size; /* in multiples of 256MB, except Skylake is 1GB */
 179        u8 dual_rank : 1,
 180           x16_width : 2; /* 0 means x8 width */
 181};
 182
 183static int how_many_channels(struct pci_dev *pdev)
 184{
 185        int n_channels;
 186        unsigned char capid0_2b; /* 2nd byte of CAPID0 */
 187
 188        pci_read_config_byte(pdev, IE31200_CAPID0 + 1, &capid0_2b);
 189
 190        /* check PDCD: Dual Channel Disable */
 191        if (capid0_2b & IE31200_CAPID0_PDCD) {
 192                edac_dbg(0, "In single channel mode\n");
 193                n_channels = 1;
 194        } else {
 195                edac_dbg(0, "In dual channel mode\n");
 196                n_channels = 2;
 197        }
 198
 199        /* check DDPCD - check if both channels are filled */
 200        if (capid0_2b & IE31200_CAPID0_DDPCD)
 201                edac_dbg(0, "2 DIMMS per channel disabled\n");
 202        else
 203                edac_dbg(0, "2 DIMMS per channel enabled\n");
 204
 205        return n_channels;
 206}
 207
 208static bool ecc_capable(struct pci_dev *pdev)
 209{
 210        unsigned char capid0_4b; /* 4th byte of CAPID0 */
 211
 212        pci_read_config_byte(pdev, IE31200_CAPID0 + 3, &capid0_4b);
 213        if (capid0_4b & IE31200_CAPID0_ECC)
 214                return false;
 215        return true;
 216}
 217
 218static int eccerrlog_row(u64 log)
 219{
 220        return ((log & IE31200_ECCERRLOG_RANK_BITS) >>
 221                                IE31200_ECCERRLOG_RANK_SHIFT);
 222}
 223
 224static void ie31200_clear_error_info(struct mem_ctl_info *mci)
 225{
 226        /*
 227         * Clear any error bits.
 228         * (Yes, we really clear bits by writing 1 to them.)
 229         */
 230        pci_write_bits16(to_pci_dev(mci->pdev), IE31200_ERRSTS,
 231                         IE31200_ERRSTS_BITS, IE31200_ERRSTS_BITS);
 232}
 233
 234static void ie31200_get_and_clear_error_info(struct mem_ctl_info *mci,
 235                                             struct ie31200_error_info *info)
 236{
 237        struct pci_dev *pdev;
 238        struct ie31200_priv *priv = mci->pvt_info;
 239
 240        pdev = to_pci_dev(mci->pdev);
 241
 242        /*
 243         * This is a mess because there is no atomic way to read all the
 244         * registers at once and the registers can transition from CE being
 245         * overwritten by UE.
 246         */
 247        pci_read_config_word(pdev, IE31200_ERRSTS, &info->errsts);
 248        if (!(info->errsts & IE31200_ERRSTS_BITS))
 249                return;
 250
 251        info->eccerrlog[0] = lo_hi_readq(priv->c0errlog);
 252        if (nr_channels == 2)
 253                info->eccerrlog[1] = lo_hi_readq(priv->c1errlog);
 254
 255        pci_read_config_word(pdev, IE31200_ERRSTS, &info->errsts2);
 256
 257        /*
 258         * If the error is the same for both reads then the first set
 259         * of reads is valid.  If there is a change then there is a CE
 260         * with no info and the second set of reads is valid and
 261         * should be UE info.
 262         */
 263        if ((info->errsts ^ info->errsts2) & IE31200_ERRSTS_BITS) {
 264                info->eccerrlog[0] = lo_hi_readq(priv->c0errlog);
 265                if (nr_channels == 2)
 266                        info->eccerrlog[1] =
 267                                lo_hi_readq(priv->c1errlog);
 268        }
 269
 270        ie31200_clear_error_info(mci);
 271}
 272
 273static void ie31200_process_error_info(struct mem_ctl_info *mci,
 274                                       struct ie31200_error_info *info)
 275{
 276        int channel;
 277        u64 log;
 278
 279        if (!(info->errsts & IE31200_ERRSTS_BITS))
 280                return;
 281
 282        if ((info->errsts ^ info->errsts2) & IE31200_ERRSTS_BITS) {
 283                edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0,
 284                                     -1, -1, -1, "UE overwrote CE", "");
 285                info->errsts = info->errsts2;
 286        }
 287
 288        for (channel = 0; channel < nr_channels; channel++) {
 289                log = info->eccerrlog[channel];
 290                if (log & IE31200_ECCERRLOG_UE) {
 291                        edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
 292                                             0, 0, 0,
 293                                             eccerrlog_row(log),
 294                                             channel, -1,
 295                                             "ie31200 UE", "");
 296                } else if (log & IE31200_ECCERRLOG_CE) {
 297                        edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
 298                                             0, 0,
 299                                             IE31200_ECCERRLOG_SYNDROME(log),
 300                                             eccerrlog_row(log),
 301                                             channel, -1,
 302                                             "ie31200 CE", "");
 303                }
 304        }
 305}
 306
 307static void ie31200_check(struct mem_ctl_info *mci)
 308{
 309        struct ie31200_error_info info;
 310
 311        edac_dbg(1, "MC%d\n", mci->mc_idx);
 312        ie31200_get_and_clear_error_info(mci, &info);
 313        ie31200_process_error_info(mci, &info);
 314}
 315
 316static void __iomem *ie31200_map_mchbar(struct pci_dev *pdev)
 317{
 318        union {
 319                u64 mchbar;
 320                struct {
 321                        u32 mchbar_low;
 322                        u32 mchbar_high;
 323                };
 324        } u;
 325        void __iomem *window;
 326
 327        pci_read_config_dword(pdev, IE31200_MCHBAR_LOW, &u.mchbar_low);
 328        pci_read_config_dword(pdev, IE31200_MCHBAR_HIGH, &u.mchbar_high);
 329        u.mchbar &= IE31200_MCHBAR_MASK;
 330
 331        if (u.mchbar != (resource_size_t)u.mchbar) {
 332                ie31200_printk(KERN_ERR, "mmio space beyond accessible range (0x%llx)\n",
 333                               (unsigned long long)u.mchbar);
 334                return NULL;
 335        }
 336
 337        window = ioremap_nocache(u.mchbar, IE31200_MMR_WINDOW_SIZE);
 338        if (!window)
 339                ie31200_printk(KERN_ERR, "Cannot map mmio space at 0x%llx\n",
 340                               (unsigned long long)u.mchbar);
 341
 342        return window;
 343}
 344
 345static void __skl_populate_dimm_info(struct dimm_data *dd, u32 addr_decode,
 346                                     int chan)
 347{
 348        dd->size = (addr_decode >> (chan << 4)) & IE31200_MAD_DIMM_SIZE;
 349        dd->dual_rank = (addr_decode & (IE31200_MAD_DIMM_A_RANK_SKL << (chan << 4))) ? 1 : 0;
 350        dd->x16_width = ((addr_decode & (IE31200_MAD_DIMM_A_WIDTH_SKL << (chan << 4))) >>
 351                                (IE31200_MAD_DIMM_A_WIDTH_SKL_SHIFT + (chan << 4)));
 352}
 353
 354static void __populate_dimm_info(struct dimm_data *dd, u32 addr_decode,
 355                                 int chan)
 356{
 357        dd->size = (addr_decode >> (chan << 3)) & IE31200_MAD_DIMM_SIZE;
 358        dd->dual_rank = (addr_decode & (IE31200_MAD_DIMM_A_RANK << chan)) ? 1 : 0;
 359        dd->x16_width = (addr_decode & (IE31200_MAD_DIMM_A_WIDTH << chan)) ? 1 : 0;
 360}
 361
 362static void populate_dimm_info(struct dimm_data *dd, u32 addr_decode, int chan,
 363                               bool skl)
 364{
 365        if (skl)
 366                __skl_populate_dimm_info(dd, addr_decode, chan);
 367        else
 368                __populate_dimm_info(dd, addr_decode, chan);
 369}
 370
 371
 372static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
 373{
 374        int i, j, ret;
 375        struct mem_ctl_info *mci = NULL;
 376        struct edac_mc_layer layers[2];
 377        struct dimm_data dimm_info[IE31200_CHANNELS][IE31200_DIMMS_PER_CHANNEL];
 378        void __iomem *window;
 379        struct ie31200_priv *priv;
 380        u32 addr_decode, mad_offset;
 381
 382        /*
 383         * Kaby Lake seems to work like Skylake. Please re-visit this logic
 384         * when adding new CPU support.
 385         */
 386        bool skl = (pdev->device >= PCI_DEVICE_ID_INTEL_IE31200_HB_8);
 387
 388        edac_dbg(0, "MC:\n");
 389
 390        if (!ecc_capable(pdev)) {
 391                ie31200_printk(KERN_INFO, "No ECC support\n");
 392                return -ENODEV;
 393        }
 394
 395        nr_channels = how_many_channels(pdev);
 396        layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
 397        layers[0].size = IE31200_DIMMS;
 398        layers[0].is_virt_csrow = true;
 399        layers[1].type = EDAC_MC_LAYER_CHANNEL;
 400        layers[1].size = nr_channels;
 401        layers[1].is_virt_csrow = false;
 402        mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
 403                            sizeof(struct ie31200_priv));
 404        if (!mci)
 405                return -ENOMEM;
 406
 407        window = ie31200_map_mchbar(pdev);
 408        if (!window) {
 409                ret = -ENODEV;
 410                goto fail_free;
 411        }
 412
 413        edac_dbg(3, "MC: init mci\n");
 414        mci->pdev = &pdev->dev;
 415        if (skl)
 416                mci->mtype_cap = MEM_FLAG_DDR4;
 417        else
 418                mci->mtype_cap = MEM_FLAG_DDR3;
 419        mci->edac_ctl_cap = EDAC_FLAG_SECDED;
 420        mci->edac_cap = EDAC_FLAG_SECDED;
 421        mci->mod_name = EDAC_MOD_STR;
 422        mci->ctl_name = ie31200_devs[dev_idx].ctl_name;
 423        mci->dev_name = pci_name(pdev);
 424        mci->edac_check = ie31200_check;
 425        mci->ctl_page_to_phys = NULL;
 426        priv = mci->pvt_info;
 427        priv->window = window;
 428        if (skl) {
 429                priv->c0errlog = window + IE31200_C0ECCERRLOG_SKL;
 430                priv->c1errlog = window + IE31200_C1ECCERRLOG_SKL;
 431                mad_offset = IE31200_MAD_DIMM_0_OFFSET_SKL;
 432        } else {
 433                priv->c0errlog = window + IE31200_C0ECCERRLOG;
 434                priv->c1errlog = window + IE31200_C1ECCERRLOG;
 435                mad_offset = IE31200_MAD_DIMM_0_OFFSET;
 436        }
 437
 438        /* populate DIMM info */
 439        for (i = 0; i < IE31200_CHANNELS; i++) {
 440                addr_decode = readl(window + mad_offset +
 441                                        (i * 4));
 442                edac_dbg(0, "addr_decode: 0x%x\n", addr_decode);
 443                for (j = 0; j < IE31200_DIMMS_PER_CHANNEL; j++) {
 444                        populate_dimm_info(&dimm_info[i][j], addr_decode, j,
 445                                           skl);
 446                        edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n",
 447                                 dimm_info[i][j].size,
 448                                 dimm_info[i][j].dual_rank,
 449                                 dimm_info[i][j].x16_width);
 450                }
 451        }
 452
 453        /*
 454         * The dram rank boundary (DRB) reg values are boundary addresses
 455         * for each DRAM rank with a granularity of 64MB.  DRB regs are
 456         * cumulative; the last one will contain the total memory
 457         * contained in all ranks.
 458         */
 459        for (i = 0; i < IE31200_DIMMS_PER_CHANNEL; i++) {
 460                for (j = 0; j < IE31200_CHANNELS; j++) {
 461                        struct dimm_info *dimm;
 462                        unsigned long nr_pages;
 463
 464                        nr_pages = IE31200_PAGES(dimm_info[j][i].size, skl);
 465                        if (nr_pages == 0)
 466                                continue;
 467
 468                        if (dimm_info[j][i].dual_rank) {
 469                                nr_pages = nr_pages / 2;
 470                                dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
 471                                                     mci->n_layers, (i * 2) + 1,
 472                                                     j, 0);
 473                                dimm->nr_pages = nr_pages;
 474                                edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
 475                                dimm->grain = 8; /* just a guess */
 476                                if (skl)
 477                                        dimm->mtype = MEM_DDR4;
 478                                else
 479                                        dimm->mtype = MEM_DDR3;
 480                                dimm->dtype = DEV_UNKNOWN;
 481                                dimm->edac_mode = EDAC_UNKNOWN;
 482                        }
 483                        dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
 484                                             mci->n_layers, i * 2, j, 0);
 485                        dimm->nr_pages = nr_pages;
 486                        edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
 487                        dimm->grain = 8; /* same guess */
 488                        if (skl)
 489                                dimm->mtype = MEM_DDR4;
 490                        else
 491                                dimm->mtype = MEM_DDR3;
 492                        dimm->dtype = DEV_UNKNOWN;
 493                        dimm->edac_mode = EDAC_UNKNOWN;
 494                }
 495        }
 496
 497        ie31200_clear_error_info(mci);
 498
 499        if (edac_mc_add_mc(mci)) {
 500                edac_dbg(3, "MC: failed edac_mc_add_mc()\n");
 501                ret = -ENODEV;
 502                goto fail_unmap;
 503        }
 504
 505        /* get this far and it's successful */
 506        edac_dbg(3, "MC: success\n");
 507        return 0;
 508
 509fail_unmap:
 510        iounmap(window);
 511
 512fail_free:
 513        edac_mc_free(mci);
 514
 515        return ret;
 516}
 517
 518static int ie31200_init_one(struct pci_dev *pdev,
 519                            const struct pci_device_id *ent)
 520{
 521        edac_dbg(0, "MC:\n");
 522
 523        if (pci_enable_device(pdev) < 0)
 524                return -EIO;
 525
 526        return ie31200_probe1(pdev, ent->driver_data);
 527}
 528
 529static void ie31200_remove_one(struct pci_dev *pdev)
 530{
 531        struct mem_ctl_info *mci;
 532        struct ie31200_priv *priv;
 533
 534        edac_dbg(0, "\n");
 535        mci = edac_mc_del_mc(&pdev->dev);
 536        if (!mci)
 537                return;
 538        priv = mci->pvt_info;
 539        iounmap(priv->window);
 540        edac_mc_free(mci);
 541}
 542
 543static const struct pci_device_id ie31200_pci_tbl[] = {
 544        {
 545                PCI_VEND_DEV(INTEL, IE31200_HB_1), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 546                IE31200},
 547        {
 548                PCI_VEND_DEV(INTEL, IE31200_HB_2), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 549                IE31200},
 550        {
 551                PCI_VEND_DEV(INTEL, IE31200_HB_3), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 552                IE31200},
 553        {
 554                PCI_VEND_DEV(INTEL, IE31200_HB_4), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 555                IE31200},
 556        {
 557                PCI_VEND_DEV(INTEL, IE31200_HB_5), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 558                IE31200},
 559        {
 560                PCI_VEND_DEV(INTEL, IE31200_HB_6), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 561                IE31200},
 562        {
 563                PCI_VEND_DEV(INTEL, IE31200_HB_7), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 564                IE31200},
 565        {
 566                PCI_VEND_DEV(INTEL, IE31200_HB_8), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 567                IE31200},
 568        {
 569                PCI_VEND_DEV(INTEL, IE31200_HB_9), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 570                IE31200},
 571        {
 572                0,
 573        }            /* 0 terminated list. */
 574};
 575MODULE_DEVICE_TABLE(pci, ie31200_pci_tbl);
 576
 577static struct pci_driver ie31200_driver = {
 578        .name = EDAC_MOD_STR,
 579        .probe = ie31200_init_one,
 580        .remove = ie31200_remove_one,
 581        .id_table = ie31200_pci_tbl,
 582};
 583
 584static int __init ie31200_init(void)
 585{
 586        edac_dbg(3, "MC:\n");
 587        /* Ensure that the OPSTATE is set correctly for POLL or NMI */
 588        opstate_init();
 589
 590        return pci_register_driver(&ie31200_driver);
 591}
 592
 593static void __exit ie31200_exit(void)
 594{
 595        edac_dbg(3, "MC:\n");
 596        pci_unregister_driver(&ie31200_driver);
 597}
 598
 599module_init(ie31200_init);
 600module_exit(ie31200_exit);
 601
 602MODULE_LICENSE("GPL");
 603MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
 604MODULE_DESCRIPTION("MC support for Intel Processor E31200 memory hub controllers");
 605