/*
* Freescale MPC85xx Memory Controller kenel module
*
* Author: Dave Jiang <djiang@mvista.com>
*
* 2006-2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/ctype.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/edac.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
#include "edac_module.h"
#include "edac_core.h"
#include "mpc85xx_edac.h"
static int edac_dev_idx;
static int edac_pci_idx;
static int edac_mc_idx;
static u32 orig_ddr_err_disable;
static u32 orig_ddr_err_sbe;
/*
* PCI Err defines
*/
#ifdef CONFIG_PCI
static u32 orig_pci_err_cap_dr;
static u32 orig_pci_err_en;
#endif
static u32 orig_l2_err_disable;
static u32 orig_hid1;
/************************ MC SYSFS parts ***********************************/
static ssize_t mpc85xx_mc_inject_data_hi_show(struct mem_ctl_info *mci,
char *data)
{
struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
return sprintf(data, "0x%08x",
in_be32(pdata->mc_vbase +
MPC85XX_MC_DATA_ERR_INJECT_HI));
}
static ssize_t mpc85xx_mc_inject_data_lo_show(struct mem_ctl_info *mci,
char *data)
{
struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
return sprintf(data, "0x%08x",
in_be32(pdata->mc_vbase +
MPC85XX_MC_DATA_ERR_INJECT_LO));
}
static ssize_t mpc85xx_mc_inject_ctrl_show(struct mem_ctl_info *mci, char *data)
{
struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
return sprintf(data, "0x%08x",
in_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT));
}
static ssize_t mpc85xx_mc_inject_data_hi_store(struct mem_ctl_info *mci,
const char *data, size_t count)
{
struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
if (isdigit(*data)) {
out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_HI,
simple_strtoul(data, NULL, 0));
return count;
}
return 0;
}
static ssize_t mpc85xx_mc_inject_data_lo_store(struct mem_ctl_info *mci,
const char *data, size_t count)
{
struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
if (isdigit(*data)) {
out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_LO,
simple_strtoul(data, NULL, 0));
return count;
}
return 0;
}
static ssize_t mpc85xx_mc_inject_ctrl_store(struct mem_ctl_info *mci,
const char *data, size_t count)
{
struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
if (isdigit(*data)) {
out_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT,
simple_strtoul(data, NULL, 0));
return count;
}
return 0;
}
static struct mcidev_sysfs_attribute mpc85xx_mc_sysfs_attributes[] = {
{
.attr = {
.name = "inject_data_hi",
.mode = (S_IRUGO | S_IWUSR)
},
.show = mpc85xx_mc_inject_data_hi_show,
.store = mpc85xx_mc_inject_data_hi_store},
{
.attr = {
.name = "inject_data_lo",
.mode = (S_IRUGO | S_IWUSR)
},
.show = mpc85xx_mc_inject_data_lo_show,
.store = mpc85xx_mc_inject_data_lo_store},
{
.attr = {
.name = "inject_ctrl",
.mode = (S_IRUGO | S_IWUSR)
},
.show = mpc85xx_mc_inject_ctrl_show,
.store = mpc85xx_mc_inject_ctrl_store},
/* End of list */
{
.attr = {.name = NULL}
}
};
static void mpc85xx_set_mc_sysfs_attributes(struct mem_ctl_info *mci)
{
mci->mc_driver_sysfs_attributes = mpc85xx_mc_sysfs_attributes;
}
/**************************** PCI Err device ***************************/
#ifdef CONFIG_PCI
static