linux/drivers/edac/amd8131_edac.c
<<
>>
Prefs
   1/*
   2 * amd8131_edac.c, AMD8131 hypertransport 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/io.h>
  28#include <linux/bitops.h>
  29#include <linux/edac.h>
  30#include <linux/pci_ids.h>
  31
  32#include "edac_core.h"
  33#include "edac_module.h"
  34#include "amd8131_edac.h"
  35
  36#define AMD8131_EDAC_REVISION   " Ver: 1.0.0"
  37#define AMD8131_EDAC_MOD_STR    "amd8131_edac"
  38
  39/* Wrapper functions for accessing PCI configuration space */
  40static void edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
  41{
  42        int ret;
  43
  44        ret = pci_read_config_dword(dev, reg, val32);
  45        if (ret != 0)
  46                printk(KERN_ERR AMD8131_EDAC_MOD_STR
  47                        " PCI Access Read Error at 0x%x\n", reg);
  48}
  49
  50static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
  51{
  52        int ret;
  53
  54        ret = pci_write_config_dword(dev, reg, val32);
  55        if (ret != 0)
  56                printk(KERN_ERR AMD8131_EDAC_MOD_STR
  57                        " PCI Access Write Error at 0x%x\n", reg);
  58}
  59
  60static char * const bridge_str[] = {
  61        [NORTH_A] = "NORTH A",
  62        [NORTH_B] = "NORTH B",
  63        [SOUTH_A] = "SOUTH A",
  64        [SOUTH_B] = "SOUTH B",
  65        [NO_BRIDGE] = "NO BRIDGE",
  66};
  67
  68/* Support up to two AMD8131 chipsets on a platform */
  69static struct amd8131_dev_info amd8131_devices[] = {
  70        {
  71        .inst = NORTH_A,
  72        .devfn = DEVFN_PCIX_BRIDGE_NORTH_A,
  73        .ctl_name = "AMD8131_PCIX_NORTH_A",
  74        },
  75        {
  76        .inst = NORTH_B,
  77        .devfn = DEVFN_PCIX_BRIDGE_NORTH_B,
  78        .ctl_name = "AMD8131_PCIX_NORTH_B",
  79        },
  80        {
  81        .inst = SOUTH_A,
  82        .devfn = DEVFN_PCIX_BRIDGE_SOUTH_A,
  83        .ctl_name = "AMD8131_PCIX_SOUTH_A",
  84        },
  85        {
  86        .inst = SOUTH_B,
  87        .devfn = DEVFN_PCIX_BRIDGE_SOUTH_B,
  88        .ctl_name = "AMD8131_PCIX_SOUTH_B",
  89        },
  90        {.inst = NO_BRIDGE,},
  91};
  92
  93static void amd8131_pcix_init(struct amd8131_dev_info *dev_info)
  94{
  95        u32 val32;
  96        struct pci_dev *dev = dev_info->dev;
  97
  98        /* First clear error detection flags */
  99        edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
 100        if (val32 & MEM_LIMIT_MASK)
 101                edac_pci_write_dword(dev, REG_MEM_LIM, val32);
 102
 103        /* Clear Discard Timer Timedout flag */
 104        edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
 105        if (val32 & INT_CTLR_DTS)
 106                edac_pci_write_dword(dev, REG_INT_CTLR, val32);
 107
 108        /* Clear CRC Error flag on link side A */
 109        edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
 110        if (val32 & LNK_CTRL_CRCERR_A)
 111                edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
 112
 113        /* Clear CRC Error flag on link side B */
 114        edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
 115        if (val32 & LNK_CTRL_CRCERR_B)
 116                edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
 117
 118        /*
 119         * Then enable all error detections.
 120         *
 121         * Setup Discard Timer Sync Flood Enable,
 122         * System Error Enable and Parity Error Enable.
 123         */
 124        edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
 125        val32 |= INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE;
 126        edac_pci_write_dword(dev, REG_INT_CTLR, val32);
 127
 128        /* Enable overall SERR Error detection */
 129        edac_pci_read_dword(dev, REG_STS_CMD, &val32);
 130        val32 |= STS_CMD_SERREN;
 131        edac_pci_write_dword(dev, REG_STS_CMD, val32);
 132
 133        /* Setup CRC Flood Enable for link side A */
 134        edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
 135        val32 |= LNK_CTRL_CRCFEN;
 136        edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
 137
 138        /* Setup CRC Flood Enable for link side B */
 139        edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
 140        val32 |= LNK_CTRL_CRCFEN;
 141        edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
 142}
 143
 144static void amd8131_pcix_exit(struct amd8131_dev_info *dev_info)
 145{
 146        u32 val32;
 147        struct pci_dev *dev = dev_info->dev;
 148
 149        /* Disable SERR, PERR and DTSE Error detection */
 150        edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
 151        val32 &= ~(INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE);
 152        edac_pci_write_dword(dev, REG_INT_CTLR, val32);
 153
 154        /* Disable overall System Error detection */
 155        edac_pci_read_dword(dev, REG_STS_CMD, &val32);
 156        val32 &= ~STS_CMD_SERREN;
 157        edac_pci_write_dword(dev, REG_STS_CMD, val32);
 158
 159        /* Disable CRC Sync Flood on link side A */
 160        edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
 161        val32 &= ~LNK_CTRL_CRCFEN;
 162        edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
 163
 164        /* Disable CRC Sync Flood on link side B */
 165        edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
 166        val32 &= ~LNK_CTRL_CRCFEN;
 167        edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
 168}
 169
 170static void amd8131_pcix_check(struct edac_pci_ctl_info *edac_dev)
 171{
 172        struct amd8131_dev_info *dev_info = edac_dev->pvt_info;
 173        struct pci_dev *dev = dev_info->dev;
 174        u32 val32;
 175
 176        /* Check PCI-X Bridge Memory Base-Limit Register for errors */
 177        edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
 178        if (val32 & MEM_LIMIT_MASK) {
 179                printk(KERN_INFO "Error(s) in mem limit register "
 180                        "on %s bridge\n", dev_info->ctl_name);
 181                printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
 182                        "RTA: %d, STA: %d, MDPE: %d\n",
 183                        val32 & MEM_LIMIT_DPE,
 184                        val32 & MEM_LIMIT_RSE,
 185                        val32 & MEM_LIMIT_RMA,
 186                        val32 & MEM_LIMIT_RTA,
 187                        val32 & MEM_LIMIT_STA,
 188                        val32 & MEM_LIMIT_MDPE);
 189
 190                val32 |= MEM_LIMIT_MASK;
 191                edac_pci_write_dword(dev, REG_MEM_LIM, val32);
 192
 193                edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
 194        }
 195
 196        /* Check if Discard Timer timed out */
 197        edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
 198        if (val32 & INT_CTLR_DTS) {
 199                printk(KERN_INFO "Error(s) in interrupt and control register "
 200                        "on %s bridge\n", dev_info->ctl_name);
 201                printk(KERN_INFO "DTS: %d\n", val32 & INT_CTLR_DTS);
 202
 203                val32 |= INT_CTLR_DTS;
 204                edac_pci_write_dword(dev, REG_INT_CTLR, val32);
 205
 206                edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
 207        }
 208
 209        /* Check if CRC error happens on link side A */
 210        edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
 211        if (val32 & LNK_CTRL_CRCERR_A) {
 212                printk(KERN_INFO "Error(s) in link conf and control register "
 213                        "on %s bridge\n", dev_info->ctl_name);
 214                printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_A);
 215
 216                val32 |= LNK_CTRL_CRCERR_A;
 217                edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
 218
 219                edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
 220        }
 221
 222        /* Check if CRC error happens on link side B */
 223        edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
 224        if (val32 & LNK_CTRL_CRCERR_B) {
 225                printk(KERN_INFO "Error(s) in link conf and control register "
 226                        "on %s bridge\n", dev_info->ctl_name);
 227                printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_B);
 228
 229                val32 |= LNK_CTRL_CRCERR_B;
 230                edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
 231
 232                edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
 233        }
 234}
 235
 236static struct amd8131_info amd8131_chipset = {
 237        .err_dev = PCI_DEVICE_ID_AMD_8131_APIC,
 238        .devices = amd8131_devices,
 239        .init = amd8131_pcix_init,
 240        .exit = amd8131_pcix_exit,
 241        .check = amd8131_pcix_check,
 242};
 243
 244/*
 245 * There are 4 PCIX Bridges on ATCA-6101 that share the same PCI Device ID,
 246 * so amd8131_probe() would be called by kernel 4 times, with different
 247 * address of pci_dev for each of them each time.
 248 */
 249static int amd8131_probe(struct pci_dev *dev, const struct pci_device_id *id)
 250{
 251        struct amd8131_dev_info *dev_info;
 252
 253        for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;
 254                dev_info++)
 255                if (dev_info->devfn == dev->devfn)
 256                        break;
 257
 258        if (dev_info->inst == NO_BRIDGE) /* should never happen */
 259                return -ENODEV;
 260
 261        /*
 262         * We can't call pci_get_device() as we are used to do because
 263         * there are 4 of them but pci_dev_get() instead.
 264         */
 265        dev_info->dev = pci_dev_get(dev);
 266
 267        if (pci_enable_device(dev_info->dev)) {
 268                pci_dev_put(dev_info->dev);
 269                printk(KERN_ERR "failed to enable:"
 270                        "vendor %x, device %x, devfn %x, name %s\n",
 271                        PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,
 272                        dev_info->devfn, dev_info->ctl_name);
 273                return -ENODEV;
 274        }
 275
 276        /*
 277         * we do not allocate extra private structure for
 278         * edac_pci_ctl_info, but make use of existing
 279         * one instead.
 280         */
 281        dev_info->edac_idx = edac_pci_alloc_index();
 282        dev_info->edac_dev = edac_pci_alloc_ctl_info(0, dev_info->ctl_name);
 283        if (!dev_info->edac_dev)
 284                return -ENOMEM;
 285
 286        dev_info->edac_dev->pvt_info = dev_info;
 287        dev_info->edac_dev->dev = &dev_info->dev->dev;
 288        dev_info->edac_dev->mod_name = AMD8131_EDAC_MOD_STR;
 289        dev_info->edac_dev->ctl_name = dev_info->ctl_name;
 290        dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);
 291
 292        if (edac_op_state == EDAC_OPSTATE_POLL)
 293                dev_info->edac_dev->edac_check = amd8131_chipset.check;
 294
 295        if (amd8131_chipset.init)
 296                amd8131_chipset.init(dev_info);
 297
 298        if (edac_pci_add_device(dev_info->edac_dev, dev_info->edac_idx) > 0) {
 299                printk(KERN_ERR "failed edac_pci_add_device() for %s\n",
 300                        dev_info->ctl_name);
 301                edac_pci_free_ctl_info(dev_info->edac_dev);
 302                return -ENODEV;
 303        }
 304
 305        printk(KERN_INFO "added one device on AMD8131 "
 306                "vendor %x, device %x, devfn %x, name %s\n",
 307                PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,
 308                dev_info->devfn, dev_info->ctl_name);
 309
 310        return 0;
 311}
 312
 313static void amd8131_remove(struct pci_dev *dev)
 314{
 315        struct amd8131_dev_info *dev_info;
 316
 317        for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;
 318                dev_info++)
 319                if (dev_info->devfn == dev->devfn)
 320                        break;
 321
 322        if (dev_info->inst == NO_BRIDGE) /* should never happen */
 323                return;
 324
 325        if (dev_info->edac_dev) {
 326                edac_pci_del_device(dev_info->edac_dev->dev);
 327                edac_pci_free_ctl_info(dev_info->edac_dev);
 328        }
 329
 330        if (amd8131_chipset.exit)
 331                amd8131_chipset.exit(dev_info);
 332
 333        pci_dev_put(dev_info->dev);
 334}
 335
 336static const struct pci_device_id amd8131_edac_pci_tbl[] = {
 337        {
 338        PCI_VEND_DEV(AMD, 8131_BRIDGE),
 339        .subvendor = PCI_ANY_ID,
 340        .subdevice = PCI_ANY_ID,
 341        .class = 0,
 342        .class_mask = 0,
 343        .driver_data = 0,
 344        },
 345        {
 346        0,
 347        }                       /* table is NULL-terminated */
 348};
 349MODULE_DEVICE_TABLE(pci, amd8131_edac_pci_tbl);
 350
 351static struct pci_driver amd8131_edac_driver = {
 352        .name = AMD8131_EDAC_MOD_STR,
 353        .probe = amd8131_probe,
 354        .remove = amd8131_remove,
 355        .id_table = amd8131_edac_pci_tbl,
 356};
 357
 358static int __init amd8131_edac_init(void)
 359{
 360        printk(KERN_INFO "AMD8131 EDAC driver " AMD8131_EDAC_REVISION "\n");
 361        printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
 362
 363        /* Only POLL mode supported so far */
 364        edac_op_state = EDAC_OPSTATE_POLL;
 365
 366        return pci_register_driver(&amd8131_edac_driver);
 367}
 368
 369static void __exit amd8131_edac_exit(void)
 370{
 371        pci_unregister_driver(&amd8131_edac_driver);
 372}
 373
 374module_init(amd8131_edac_init);
 375module_exit(amd8131_edac_exit);
 376
 377MODULE_LICENSE("GPL");
 378MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>\n");
 379MODULE_DESCRIPTION("AMD8131 HyperTransport PCI-X Tunnel EDAC kernel module");
 380
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.