#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
+#include <linux/edac.h>
#include "edac_core.h"
#define R82600_REVISION " Ver: 2.0.2 " __DATE__
u32 eapr;
};
-static unsigned int disable_hardware_scrub = 0;
+static unsigned int disable_hardware_scrub;
+
+static struct edac_pci_ctl_info *r82600_pci;
static void r82600_get_error_info(struct mem_ctl_info *mci,
- struct r82600_error_info *info)
+ struct r82600_error_info *info)
{
struct pci_dev *pdev;
}
static int r82600_process_error_info(struct mem_ctl_info *mci,
- struct r82600_error_info *info,
- int handle_errors)
+ struct r82600_error_info *info,
+ int handle_errors)
{
int error_found;
u32 eapaddr, page;
if (handle_errors)
edac_mc_handle_ce(mci, page, 0, /* not avail */
- syndrome, edac_mc_find_csrow_by_page(mci, page), 0, /* channel */
- mci->ctl_name);
+ syndrome,
+ edac_mc_find_csrow_by_page(mci, page),
+ 0, mci->ctl_name);
}
if (info->eapr & BIT(1)) { /* UE? */
if (handle_errors)
/* 82600 doesn't give enough info */
edac_mc_handle_ue(mci, page, 0,
- edac_mc_find_csrow_by_page(mci, page),
- mci->ctl_name);
+ edac_mc_find_csrow_by_page(mci, page),
+ mci->ctl_name);
}
return error_found;
}
static void r82600_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
- u8 dramcr)
+ u8 dramcr)
{
struct csrow_info *csrow;
int index;
debugf2("%s(): sdram refresh rate = %#0x\n", __func__,
sdram_refresh_rate);
debugf2("%s(): DRAMC register = %#0x\n", __func__, dramcr);
- mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS);
+ mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS, 0);
if (mci == NULL)
return -ENOMEM;
/* Here we assume that we will never see multiple instances of this
* type of memory controller. The ID is therefore hardcoded to 0.
*/
- if (edac_mc_add_mc(mci, 0)) {
+ if (edac_mc_add_mc(mci)) {
debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
goto fail;
}
pci_write_bits32(pdev, R82600_EAP, BIT(31), BIT(31));
}
+ /* allocating generic PCI control info */
+ r82600_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
+ if (!r82600_pci) {
+ printk(KERN_WARNING
+ "%s(): Unable to create PCI control\n",
+ __func__);
+ printk(KERN_WARNING
+ "%s(): PCI error report via EDAC not setup\n",
+ __func__);
+ }
+
debugf3("%s(): success\n", __func__);
return 0;
- fail:
+fail:
edac_mc_free(mci);
return -ENODEV;
}
/* returns count (>= 0), or negative on error */
static int __devinit r82600_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *ent)
{
debugf0("%s()\n", __func__);
debugf0("%s()\n", __func__);
+ if (r82600_pci)
+ edac_pci_release_generic_ctl(r82600_pci);
+
if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
return;
static int __init r82600_init(void)
{
+ /* Ensure that the OPSTATE is set correctly for POLL or NMI */
+ opstate_init();
+
return pci_register_driver(&r82600_driver);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD Ltd. "
- "on behalf of EADS Astrium");
+ "on behalf of EADS Astrium");
MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers");
module_param(disable_hardware_scrub, bool, 0644);
MODULE_PARM_DESC(disable_hardware_scrub,
"If set, disable the chipset's automatic scrub for CEs");
+
+module_param(edac_op_state, int, 0444);
+MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");