Commit 1a370f4c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'edac_for_4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp

Pull EDAC updates from Borislav Petkov:

 - convert a bunch of drivers to static attribute groups (Takashi Iwai)

 - misc cleanups

* tag 'edac_for_4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
  EDAC: Constify of_device_id array
  EDAC, i82443bxgx: Don't export static symbol
  EDAC, amd64_edac: Get rid of per-node driver instances
  EDAC: Properly unwind on failure path in edac_init()
  EDAC: highbank: Use static attribute groups for sysfs entries
  EDAC: octeon: Use static attribute groups for sysfs entries
  EDAC: mpc85xx: Use static attribute groups for sysfs entries
  EDAC: i7core: Use static attribute groups for sysfs entries
  EDAC: i7core: Return proper error codes for kzalloc() errors
  EDAC: amd64: Use static attribute groups
  EDAC: Allow to pass driver-specific attribute groups
  EDAC: Use static attribute groups for managing sysfs entries
  EDAC: Delete unnecessary checks before pci_dev_put()
parents 4b5ca741 1afaa055
...@@ -20,8 +20,7 @@ static struct msr __percpu *msrs; ...@@ -20,8 +20,7 @@ static struct msr __percpu *msrs;
*/ */
static atomic_t drv_instances = ATOMIC_INIT(0); static atomic_t drv_instances = ATOMIC_INIT(0);
/* Per-node driver instances */ /* Per-node stuff */
static struct mem_ctl_info **mcis;
static struct ecc_settings **ecc_stngs; static struct ecc_settings **ecc_stngs;
/* /*
...@@ -903,9 +902,17 @@ static int k8_early_channel_count(struct amd64_pvt *pvt) ...@@ -903,9 +902,17 @@ static int k8_early_channel_count(struct amd64_pvt *pvt)
/* On F10h and later ErrAddr is MC4_ADDR[47:1] */ /* On F10h and later ErrAddr is MC4_ADDR[47:1] */
static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m) static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m)
{ {
u64 addr; u16 mce_nid = amd_get_nb_id(m->extcpu);
struct mem_ctl_info *mci;
u8 start_bit = 1; u8 start_bit = 1;
u8 end_bit = 47; u8 end_bit = 47;
u64 addr;
mci = edac_mc_find(mce_nid);
if (!mci)
return 0;
pvt = mci->pvt_info;
if (pvt->fam == 0xf) { if (pvt->fam == 0xf) {
start_bit = 3; start_bit = 3;
...@@ -918,17 +925,13 @@ static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m) ...@@ -918,17 +925,13 @@ static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m)
* Erratum 637 workaround * Erratum 637 workaround
*/ */
if (pvt->fam == 0x15) { if (pvt->fam == 0x15) {
struct amd64_pvt *pvt;
u64 cc6_base, tmp_addr; u64 cc6_base, tmp_addr;
u32 tmp; u32 tmp;
u16 mce_nid;
u8 intlv_en; u8 intlv_en;
if ((addr & GENMASK_ULL(47, 24)) >> 24 != 0x00fdf7) if ((addr & GENMASK_ULL(47, 24)) >> 24 != 0x00fdf7)
return addr; return addr;
mce_nid = amd_get_nb_id(m->extcpu);
pvt = mcis[mce_nid]->pvt_info;
amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_LIM, &tmp); amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_LIM, &tmp);
intlv_en = tmp >> 21 & 0x7; intlv_en = tmp >> 21 & 0x7;
...@@ -1511,7 +1514,7 @@ static int f1x_lookup_addr_in_dct(u64 in_addr, u8 nid, u8 dct) ...@@ -1511,7 +1514,7 @@ static int f1x_lookup_addr_in_dct(u64 in_addr, u8 nid, u8 dct)
int cs_found = -EINVAL; int cs_found = -EINVAL;
int csrow; int csrow;
mci = mcis[nid]; mci = edac_mc_find(nid);
if (!mci) if (!mci)
return cs_found; return cs_found;
...@@ -2663,34 +2666,6 @@ static bool ecc_enabled(struct pci_dev *F3, u16 nid) ...@@ -2663,34 +2666,6 @@ static bool ecc_enabled(struct pci_dev *F3, u16 nid)
return true; return true;
} }
static int set_mc_sysfs_attrs(struct mem_ctl_info *mci)
{
struct amd64_pvt *pvt = mci->pvt_info;
int rc;
rc = amd64_create_sysfs_dbg_files(mci);
if (rc < 0)
return rc;
if (pvt->fam >= 0x10) {
rc = amd64_create_sysfs_inject_files(mci);
if (rc < 0)
return rc;
}
return 0;
}
static void del_mc_sysfs_attrs(struct mem_ctl_info *mci)
{
struct amd64_pvt *pvt = mci->pvt_info;
amd64_remove_sysfs_dbg_files(mci);
if (pvt->fam >= 0x10)
amd64_remove_sysfs_inject_files(mci);
}
static void setup_mci_misc_attrs(struct mem_ctl_info *mci, static void setup_mci_misc_attrs(struct mem_ctl_info *mci,
struct amd64_family_type *fam) struct amd64_family_type *fam)
{ {
...@@ -2778,6 +2753,16 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt) ...@@ -2778,6 +2753,16 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt)
return fam_type; return fam_type;
} }
static const struct attribute_group *amd64_edac_attr_groups[] = {
#ifdef CONFIG_EDAC_DEBUG
&amd64_edac_dbg_group,
#endif
#ifdef CONFIG_EDAC_AMD64_ERROR_INJECTION
&amd64_edac_inj_group,
#endif
NULL
};
static int init_one_instance(struct pci_dev *F2) static int init_one_instance(struct pci_dev *F2)
{ {
struct amd64_pvt *pvt = NULL; struct amd64_pvt *pvt = NULL;
...@@ -2844,14 +2829,10 @@ static int init_one_instance(struct pci_dev *F2) ...@@ -2844,14 +2829,10 @@ static int init_one_instance(struct pci_dev *F2)
mci->edac_cap = EDAC_FLAG_NONE; mci->edac_cap = EDAC_FLAG_NONE;
ret = -ENODEV; ret = -ENODEV;
if (edac_mc_add_mc(mci)) { if (edac_mc_add_mc_with_groups(mci, amd64_edac_attr_groups)) {
edac_dbg(1, "failed edac_mc_add_mc()\n"); edac_dbg(1, "failed edac_mc_add_mc()\n");
goto err_add_mc; goto err_add_mc;
} }
if (set_mc_sysfs_attrs(mci)) {
edac_dbg(1, "failed edac_mc_add_mc()\n");
goto err_add_sysfs;
}
/* register stuff with EDAC MCE */ /* register stuff with EDAC MCE */
if (report_gart_errors) if (report_gart_errors)
...@@ -2859,14 +2840,10 @@ static int init_one_instance(struct pci_dev *F2) ...@@ -2859,14 +2840,10 @@ static int init_one_instance(struct pci_dev *F2)
amd_register_ecc_decoder(decode_bus_error); amd_register_ecc_decoder(decode_bus_error);
mcis[nid] = mci;
atomic_inc(&drv_instances); atomic_inc(&drv_instances);
return 0; return 0;
err_add_sysfs:
edac_mc_del_mc(mci->pdev);
err_add_mc: err_add_mc:
edac_mc_free(mci); edac_mc_free(mci);
...@@ -2940,7 +2917,6 @@ static void remove_one_instance(struct pci_dev *pdev) ...@@ -2940,7 +2917,6 @@ static void remove_one_instance(struct pci_dev *pdev)
mci = find_mci_by_dev(&pdev->dev); mci = find_mci_by_dev(&pdev->dev);
WARN_ON(!mci); WARN_ON(!mci);
del_mc_sysfs_attrs(mci);
/* Remove from EDAC CORE tracking list */ /* Remove from EDAC CORE tracking list */
mci = edac_mc_del_mc(&pdev->dev); mci = edac_mc_del_mc(&pdev->dev);
if (!mci) if (!mci)
...@@ -2961,7 +2937,6 @@ static void remove_one_instance(struct pci_dev *pdev) ...@@ -2961,7 +2937,6 @@ static void remove_one_instance(struct pci_dev *pdev)
/* Free the EDAC CORE resources */ /* Free the EDAC CORE resources */
mci->pvt_info = NULL; mci->pvt_info = NULL;
mcis[nid] = NULL;
kfree(pvt); kfree(pvt);
edac_mc_free(mci); edac_mc_free(mci);
...@@ -2999,7 +2974,7 @@ static void setup_pci_device(void) ...@@ -2999,7 +2974,7 @@ static void setup_pci_device(void)
if (pci_ctl) if (pci_ctl)
return; return;
mci = mcis[0]; mci = edac_mc_find(0);
if (!mci) if (!mci)
return; return;
...@@ -3023,9 +2998,8 @@ static int __init amd64_edac_init(void) ...@@ -3023,9 +2998,8 @@ static int __init amd64_edac_init(void)
goto err_ret; goto err_ret;
err = -ENOMEM; err = -ENOMEM;
mcis = kzalloc(amd_nb_num() * sizeof(mcis[0]), GFP_KERNEL);
ecc_stngs = kzalloc(amd_nb_num() * sizeof(ecc_stngs[0]), GFP_KERNEL); ecc_stngs = kzalloc(amd_nb_num() * sizeof(ecc_stngs[0]), GFP_KERNEL);
if (!(mcis && ecc_stngs)) if (!ecc_stngs)
goto err_free; goto err_free;
msrs = msrs_alloc(); msrs = msrs_alloc();
...@@ -3056,9 +3030,6 @@ static int __init amd64_edac_init(void) ...@@ -3056,9 +3030,6 @@ static int __init amd64_edac_init(void)
msrs = NULL; msrs = NULL;
err_free: err_free:
kfree(mcis);
mcis = NULL;
kfree(ecc_stngs); kfree(ecc_stngs);
ecc_stngs = NULL; ecc_stngs = NULL;
...@@ -3076,9 +3047,6 @@ static void __exit amd64_edac_exit(void) ...@@ -3076,9 +3047,6 @@ static void __exit amd64_edac_exit(void)
kfree(ecc_stngs); kfree(ecc_stngs);
ecc_stngs = NULL; ecc_stngs = NULL;
kfree(mcis);
mcis = NULL;
msrs_free(msrs); msrs_free(msrs);
msrs = NULL; msrs = NULL;
} }
......
...@@ -453,31 +453,11 @@ struct ecc_settings { ...@@ -453,31 +453,11 @@ struct ecc_settings {
}; };
#ifdef CONFIG_EDAC_DEBUG #ifdef CONFIG_EDAC_DEBUG
int amd64_create_sysfs_dbg_files(struct mem_ctl_info *mci); extern const struct attribute_group amd64_edac_dbg_group;
void amd64_remove_sysfs_dbg_files(struct mem_ctl_info *mci);
#else
static inline int amd64_create_sysfs_dbg_files(struct mem_ctl_info *mci)
{
return 0;
}
static void inline amd64_remove_sysfs_dbg_files(struct mem_ctl_info *mci)
{
}
#endif #endif
#ifdef CONFIG_EDAC_AMD64_ERROR_INJECTION #ifdef CONFIG_EDAC_AMD64_ERROR_INJECTION
int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci); extern const struct attribute_group amd64_edac_inj_group;
void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci);
#else
static inline int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci)
{
return 0;
}
static inline void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci)
{
}
#endif #endif
/* /*
......
...@@ -40,34 +40,15 @@ static DEVICE_ATTR(topmem, S_IRUGO, amd64_top_mem_show, NULL); ...@@ -40,34 +40,15 @@ static DEVICE_ATTR(topmem, S_IRUGO, amd64_top_mem_show, NULL);
static DEVICE_ATTR(topmem2, S_IRUGO, amd64_top_mem2_show, NULL); static DEVICE_ATTR(topmem2, S_IRUGO, amd64_top_mem2_show, NULL);
static DEVICE_ATTR(dram_hole, S_IRUGO, amd64_hole_show, NULL); static DEVICE_ATTR(dram_hole, S_IRUGO, amd64_hole_show, NULL);
int amd64_create_sysfs_dbg_files(struct mem_ctl_info *mci) static struct attribute *amd64_edac_dbg_attrs[] = {
{ &dev_attr_dhar.attr,
int rc; &dev_attr_dbam.attr,
&dev_attr_topmem.attr,
rc = device_create_file(&mci->dev, &dev_attr_dhar); &dev_attr_topmem2.attr,
if (rc < 0) &dev_attr_dram_hole.attr,
return rc; NULL
rc = device_create_file(&mci->dev, &dev_attr_dbam); };
if (rc < 0)
return rc; const struct attribute_group amd64_edac_dbg_group = {
rc = device_create_file(&mci->dev, &dev_attr_topmem); .attrs = amd64_edac_dbg_attrs,
if (rc < 0) };
return rc;
rc = device_create_file(&mci->dev, &dev_attr_topmem2);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_dram_hole);
if (rc < 0)
return rc;
return 0;
}
void amd64_remove_sysfs_dbg_files(struct mem_ctl_info *mci)
{
device_remove_file(&mci->dev, &dev_attr_dhar);
device_remove_file(&mci->dev, &dev_attr_dbam);
device_remove_file(&mci->dev, &dev_attr_topmem);
device_remove_file(&mci->dev, &dev_attr_topmem2);
device_remove_file(&mci->dev, &dev_attr_dram_hole);
}
...@@ -207,35 +207,28 @@ static DEVICE_ATTR(inject_write, S_IWUSR, ...@@ -207,35 +207,28 @@ static DEVICE_ATTR(inject_write, S_IWUSR,
static DEVICE_ATTR(inject_read, S_IWUSR, static DEVICE_ATTR(inject_read, S_IWUSR,
NULL, amd64_inject_read_store); NULL, amd64_inject_read_store);
static struct attribute *amd64_edac_inj_attrs[] = {
int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci) &dev_attr_inject_section.attr,
&dev_attr_inject_word.attr,
&dev_attr_inject_ecc_vector.attr,
&dev_attr_inject_write.attr,
&dev_attr_inject_read.attr,
NULL
};
static umode_t amd64_edac_inj_is_visible(struct kobject *kobj,
struct attribute *attr, int idx)
{ {
int rc; struct device *dev = kobj_to_dev(kobj);
struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev);
rc = device_create_file(&mci->dev, &dev_attr_inject_section); struct amd64_pvt *pvt = mci->pvt_info;
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_word);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_ecc_vector);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_write);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_read);
if (rc < 0)
return rc;
return 0;
}
void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci) if (pvt->fam < 0x10)
{ return 0;
device_remove_file(&mci->dev, &dev_attr_inject_section); return attr->mode;
device_remove_file(&mci->dev, &dev_attr_inject_word);
device_remove_file(&mci->dev, &dev_attr_inject_ecc_vector);
device_remove_file(&mci->dev, &dev_attr_inject_write);
device_remove_file(&mci->dev, &dev_attr_inject_read);
} }
const struct attribute_group amd64_edac_inj_group = {
.attrs = amd64_edac_inj_attrs,
.is_visible = amd64_edac_inj_is_visible,
};
...@@ -446,7 +446,9 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, ...@@ -446,7 +446,9 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
unsigned n_layers, unsigned n_layers,
struct edac_mc_layer *layers, struct edac_mc_layer *layers,
unsigned sz_pvt); unsigned sz_pvt);
extern int edac_mc_add_mc(struct mem_ctl_info *mci); extern int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
const struct attribute_group **groups);
#define edac_mc_add_mc(mci) edac_mc_add_mc_with_groups(mci, NULL)
extern void edac_mc_free(struct mem_ctl_info *mci); extern void edac_mc_free(struct mem_ctl_info *mci);
extern struct mem_ctl_info *edac_mc_find(int idx); extern struct mem_ctl_info *edac_mc_find(int idx);
extern struct mem_ctl_info *find_mci_by_dev(struct device *dev); extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
......
...@@ -710,9 +710,10 @@ struct mem_ctl_info *edac_mc_find(int idx) ...@@ -710,9 +710,10 @@ struct mem_ctl_info *edac_mc_find(int idx)
EXPORT_SYMBOL(edac_mc_find); EXPORT_SYMBOL(edac_mc_find);
/** /**
* edac_mc_add_mc: Insert the 'mci' structure into the mci global list and * edac_mc_add_mc_with_groups: Insert the 'mci' structure into the mci
* create sysfs entries associated with mci structure * global list and create sysfs entries associated with mci structure
* @mci: pointer to the mci structure to be added to the list * @mci: pointer to the mci structure to be added to the list
* @groups: optional attribute groups for the driver-specific sysfs entries
* *
* Return: * Return:
* 0 Success * 0 Success
...@@ -720,7 +721,8 @@ EXPORT_SYMBOL(edac_mc_find); ...@@ -720,7 +721,8 @@ EXPORT_SYMBOL(edac_mc_find);
*/ */
/* FIXME - should a warning be printed if no error detection? correction? */ /* FIXME - should a warning be printed if no error detection? correction? */
int edac_mc_add_mc(struct mem_ctl_info *mci) int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
const struct attribute_group **groups)
{ {
int ret = -EINVAL; int ret = -EINVAL;
edac_dbg(0, "\n"); edac_dbg(0, "\n");
...@@ -771,7 +773,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) ...@@ -771,7 +773,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
mci->bus = &mc_bus[mci->mc_idx]; mci->bus = &mc_bus[mci->mc_idx];
if (edac_create_sysfs_mci_device(mci)) { if (edac_create_sysfs_mci_device(mci, groups)) {
edac_mc_printk(mci, KERN_WARNING, edac_mc_printk(mci, KERN_WARNING,
"failed to create sysfs device\n"); "failed to create sysfs device\n");
goto fail1; goto fail1;
...@@ -805,7 +807,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) ...@@ -805,7 +807,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
mutex_unlock(&mem_ctls_mutex); mutex_unlock(&mem_ctls_mutex);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(edac_mc_add_mc); EXPORT_SYMBOL_GPL(edac_mc_add_mc_with_groups);
/** /**
* edac_mc_del_mc: Remove sysfs entries for specified mci structure and * edac_mc_del_mc: Remove sysfs entries for specified mci structure and
......
...@@ -323,13 +323,14 @@ DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR, ...@@ -323,13 +323,14 @@ DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR,
channel_dimm_label_show, channel_dimm_label_store, 5); channel_dimm_label_show, channel_dimm_label_store, 5);
/* Total possible dynamic DIMM Label attribute file table */ /* Total possible dynamic DIMM Label attribute file table */
static struct device_attribute *dynamic_csrow_dimm_attr[] = { static struct attribute *dynamic_csrow_dimm_attr[] = {
&dev_attr_legacy_ch0_dimm_label.attr, &dev_attr_legacy_ch0_dimm_label.attr.attr,
&dev_attr_legacy_ch1_dimm_label.attr, &dev_attr_legacy_ch1_dimm_label.attr.attr,
&dev_attr_legacy_ch2_dimm_label.attr, &dev_attr_legacy_ch2_dimm_label.attr.attr,
&dev_attr_legacy_ch3_dimm_label.attr, &dev_attr_legacy_ch3_dimm_label.attr.attr,
&dev_attr_legacy_ch4_dimm_label.attr, &dev_attr_legacy_ch4_dimm_label.attr.attr,
&dev_attr_legacy_ch5_dimm_label.attr &dev_attr_legacy_ch5_dimm_label.attr.attr,
NULL
}; };
/* possible dynamic channel ce_count attribute files */ /* possible dynamic channel ce_count attribute files */
...@@ -347,13 +348,45 @@ DEVICE_CHANNEL(ch5_ce_count, S_IRUGO, ...@@ -347,13 +348,45 @@ DEVICE_CHANNEL(ch5_ce_count, S_IRUGO,
channel_ce_count_show, NULL, 5); channel_ce_count_show, NULL, 5);
/* Total possible dynamic ce_count attribute file table */ /* Total possible dynamic ce_count attribute file table */
static struct device_attribute *dynamic_csrow_ce_count_attr[] = { static struct attribute *dynamic_csrow_ce_count_attr[] = {
&dev_attr_legacy_ch0_ce_count.attr, &dev_attr_legacy_ch0_ce_count.attr.attr,
&dev_attr_legacy_ch1_ce_count.attr, &dev_attr_legacy_ch1_ce_count.attr.attr,
&dev_attr_legacy_ch2_ce_count.attr, &dev_attr_legacy_ch2_ce_count.attr.attr,
&dev_attr_legacy_ch3_ce_count.attr, &dev_attr_legacy_ch3_ce_count.attr.attr,
&dev_attr_legacy_ch4_ce_count.attr, &dev_attr_legacy_ch4_ce_count.attr.attr,
&dev_attr_legacy_ch5_ce_count.attr &dev_attr_legacy_ch5_ce_count.attr.attr,
NULL
};
static umode_t csrow_dev_is_visible(struct kobject *kobj,
struct attribute *attr, int idx)
{
struct device *dev = kobj_to_dev(kobj);
struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);
if (idx >= csrow->nr_channels)
return 0;
/* Only expose populated DIMMs */
if (!csrow->channels[idx]->dimm->nr_pages)
return 0;
return attr->mode;
}
static const struct attribute_group csrow_dev_dimm_group = {
.attrs = dynamic_csrow_dimm_attr,
.is_visible = csrow_dev_is_visible,
};
static const struct attribute_group csrow_dev_ce_count_group = {
.attrs = dynamic_csrow_ce_count_attr,
.is_visible = csrow_dev_is_visible,
};
static const struct attribute_group *csrow_dev_groups[] = {
&csrow_dev_dimm_group,
&csrow_dev_ce_count_group,
NULL
}; };
static inline int nr_pages_per_csrow(struct csrow_info *csrow) static inline int nr_pages_per_csrow(struct csrow_info *csrow)
...@@ -370,13 +403,12 @@ static inline int nr_pages_per_csrow(struct csrow_info *csrow) ...@@ -370,13 +403,12 @@ static inline int nr_pages_per_csrow(struct csrow_info *csrow)
static int edac_create_csrow_object(struct mem_ctl_info *mci, static int edac_create_csrow_object(struct mem_ctl_info *mci,
struct csrow_info *csrow, int index) struct csrow_info *csrow, int index)
{ {
int err, chan;
if (csrow->nr_channels > EDAC_NR_CHANNELS) if (csrow->nr_channels > EDAC_NR_CHANNELS)
return -ENODEV; return -ENODEV;
csrow->dev.type = &csrow_attr_type; csrow->dev.type = &csrow_attr_type;
csrow->dev.bus = mci->bus; csrow->dev.bus = mci->bus;
csrow->dev.groups = csrow_dev_groups;
device_initialize(&csrow->dev); device_initialize(&csrow->dev);
csrow->dev.parent = &mci->dev; csrow->dev.parent = &mci->dev;
csrow->mci = mci; csrow->mci = mci;
...@@ -386,45 +418,13 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci, ...@@ -386,45 +418,13 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
edac_dbg(0, "creating (virtual) csrow node %s\n", edac_dbg(0, "creating (virtual) csrow node %s\n",
dev_name(&csrow->dev)); dev_name(&csrow->dev));
err = device_add(&csrow->dev); return device_add(&csrow->dev);
if (err < 0)
return err;
for (chan = 0; chan < csrow->nr_channels; chan++) {
/* Only expose populated DIMMs */
if (!csrow->channels[chan]->dimm->nr_pages)
continue;
err = device_create_file(&csrow->dev,
dynamic_csrow_dimm_attr[chan]);
if (err < 0)
goto error;
err = device_create_file(&csrow->dev,
dynamic_csrow_ce_count_attr[chan]);
if (err < 0) {
device_remove_file(&csrow->dev,
dynamic_csrow_dimm_attr[chan]);
goto error;
}
}
return 0;
error:
for (--chan; chan >= 0; chan--) {
device_remove_file(&csrow->dev,
dynamic_csrow_dimm_attr[chan]);
device_remove_file(&csrow->dev,
dynamic_csrow_ce_count_attr[chan]);
}
put_device(&csrow->dev);
return err;
} }
/* Create a CSROW object under specifed edac_mc_device */ /* Create a CSROW object under specifed edac_mc_device */
static int edac_create_csrow_objects(struct mem_ctl_info *mci) static int edac_create_csrow_objects(struct mem_ctl_info *mci)
{ {
int err, i, chan; int err, i;
struct csrow_info *csrow; struct csrow_info *csrow;
for (i = 0; i < mci->nr_csrows; i++) { for (i = 0; i < mci->nr_csrows; i++) {
...@@ -446,14 +446,6 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci) ...@@ -446,14 +446,6 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci)
csrow = mci->csrows[i]; csrow = mci->csrows[i];
if (!nr_pages_per_csrow(csrow)) if (!nr_pages_per_csrow(csrow))
continue; continue;
for (chan = csrow->nr_channels - 1; chan >= 0; chan--) {
if (!csrow->channels[chan]->dimm->nr_pages)
continue;
device_remove_file(&csrow->dev,
dynamic_csrow_dimm_attr[chan]);
device_remove_file(&csrow->dev,
dynamic_csrow_ce_count_attr[chan]);
}
put_device(&mci->csrows[i]->dev); put_device(&mci->csrows[i]->dev);
} }
...@@ -462,23 +454,13 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci) ...@@ -462,23 +454,13 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci)
static void edac_delete_csrow_objects(struct mem_ctl_info *mci) static void edac_delete_csrow_objects(struct mem_ctl_info *mci)
{ {
int i, chan; int i;
struct csrow_info *csrow; struct csrow_info *csrow;
for (i = mci->nr_csrows - 1; i >= 0; i--) { for (i = mci->nr_csrows - 1; i >= 0; i--) {
csrow = mci->csrows[i]; csrow = mci->csrows[i];
if (!nr_pages_per_csrow(csrow)) if (!nr_pages_per_csrow(csrow))
continue; continue;
for (chan = csrow->nr_channels - 1; chan >= 0; chan--) {
if (!csrow->channels[chan]->dimm->nr_pages)
continue;
edac_dbg(1, "Removing csrow %d channel %d sysfs nodes\n",
i, chan);
device_remove_file(&csrow->dev,
dynamic_csrow_dimm_attr[chan]);
device_remove_file(&csrow->dev,
dynamic_csrow_ce_count_attr[chan]);
}
device_unregister(&mci->csrows[i]->dev); device_unregister(&mci->csrows[i]->dev);
} }
} }
...@@ -863,7 +845,8 @@ static DEVICE_ATTR(ce_count, S_IRUGO, mci_ce_count_show, NULL); ...@@ -863,7 +845,8 @@ static DEVICE_ATTR(ce_count, S_IRUGO, mci_ce_count_show, NULL);
static DEVICE_ATTR(max_location, S_IRUGO, mci_max_location_show, NULL); static DEVICE_ATTR(max_location, S_IRUGO, mci_max_location_show, NULL);
/* memory scrubber attribute file */ /* memory scrubber attribute file */
static DEVICE_ATTR(sdram_scrub_rate, 0, NULL, NULL); DEVICE_ATTR(sdram_scrub_rate, 0, mci_sdram_scrub_rate_show,
mci_sdram_scrub_rate_store); /* umode set later in is_visible */
static struct attribute *mci_attrs[] = { static struct attribute *mci_attrs[] = {
&dev_attr_reset_counters.attr, &dev_attr_reset_counters.attr,
...@@ -875,11 +858,29 @@ static struct attribute *mci_attrs[] = { ...@@ -875,11 +858,29 @@ static struct attribute *mci_attrs[] = {
&dev_attr_ue_count.attr, &dev_attr_ue_count.attr,
&dev_attr_ce_count.attr, &dev_attr_ce_count.attr,
&dev_attr_max_location.attr, &dev_attr_max_location.attr,
&dev_attr_sdram_scrub_rate.attr,
NULL NULL
}; };
static umode_t mci_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int idx)
{
struct device *dev = kobj_to_dev(kobj);
struct mem_ctl_info *mci = to_mci(dev);
umode_t mode = 0;
if (attr != &dev_attr_sdram_scrub_rate.attr)
return attr->mode;
if (mci->get_sdram_scrub_rate)
mode |= S_IRUGO;
if (mci->set_sdram_scrub_rate)
mode |= S_IWUSR;
return mode;
}
static struct attribute_group mci_attr_grp = { static struct attribute_group mci_attr_grp = {
.attrs = mci_attrs, .attrs = mci_attrs,
.is_visible = mci_attr_is_visible,
}; };
static const struct attribute_group *mci_attr_groups[] = { static const struct attribute_group *mci_attr_groups[] = {
...@@ -913,7 +914,7 @@ int __init edac_debugfs_init(void) ...@@ -913,7 +914,7 @@ int __init edac_debugfs_init(void)
return 0; return 0;
} }
void __exit edac_debugfs_exit(void) void edac_debugfs_exit(void)
{ {
debugfs_remove(edac_debugfs); debugfs_remove(edac_debugfs);
} }
...@@ -973,7 +974,8 @@ static int edac_create_debug_nodes(struct mem_ctl_info *mci) ...@@ -973,7 +974,8 @@ static int edac_create_debug_nodes(struct mem_ctl_info *mci)
* 0 Success * 0 Success
* !0 Failure * !0 Failure
*/ */
int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
const struct attribute_group **groups)
{ {
int i, err; int i, err;
...@@ -997,6 +999,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -997,6 +999,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
mci->dev.parent = mci_pdev; mci->dev.parent = mci_pdev;
mci->dev.bus = mci->bus; mci->dev.bus = mci->bus;
mci->dev.groups = groups;
dev_set_name(&mci->dev, "mc%d", mci->mc_idx); dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
dev_set_drvdata(&mci->dev, mci); dev_set_drvdata(&mci->dev, mci);
pm_runtime_forbid(&mci->dev); pm_runtime_forbid(&mci->dev);
...@@ -1008,23 +1011,6 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -1008,23 +1011,6 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
goto fail_unregister_bus; goto fail_unregister_bus;
} }
if (mci->set_sdram_scrub_rate || mci->get_sdram_scrub_rate) {
if (mci->get_sdram_scrub_rate) {
dev_attr_sdram_scrub_rate.attr.mode |= S_IRUGO;
dev_attr_sdram_scrub_rate.show = &mci_sdram_scrub_rate_show;
}
if (mci->set_sdram_scrub_rate) {
dev_attr_sdram_scrub_rate.attr.mode |= S_IWUSR;
dev_attr_sdram_scrub_rate.store = &mci_sdram_scrub_rate_store;
}
err = device_create_file(&mci->dev, &dev_attr_sdram_scrub_rate);
if (err) {
edac_dbg(1, "failure: create sdram_scrub_rate\n");
goto fail_unregister_dev;
}
}
/* /*
* Create the dimm/rank devices * Create the dimm/rank devices
*/ */
...@@ -1071,7 +1057,6 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -1071,7 +1057,6 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
device_unregister(&dimm->dev); device_unregister(&dimm->dev);
} }
fail_unregister_dev:
device_unregister(&mci->dev); device_unregister(&mci->dev);
fail_unregister_bus: fail_unregister_bus:
bus_unregister(mci->bus); bus_unregister(mci->bus);
...@@ -1170,7 +1155,7 @@ int __init edac_mc_sysfs_init(void) ...@@ -1170,7 +1155,7 @@ int __init edac_mc_sysfs_init(void)
return err; return err;
} }
void __exit edac_mc_sysfs_exit(void) void edac_mc_sysfs_exit(void)
{ {
device_unregister(mci_pdev); device_unregister(mci_pdev);
edac_put_sysfs_subsys(); edac_put_sysfs_subsys();
......
...@@ -112,20 +112,23 @@ static int __init edac_init(void) ...@@ -112,20 +112,23 @@ static int __init edac_init(void)
err = edac_mc_sysfs_init(); err = edac_mc_sysfs_init();
if (err) if (err)
goto error; goto err_sysfs;
edac_debugfs_init(); edac_debugfs_init();
/* Setup/Initialize the workq for this core */
err = edac_workqueue_setup(); err = edac_workqueue_setup();
if (err) { if (err) {
edac_printk(KERN_ERR, EDAC_MC, "init WorkQueue failure\n"); edac_printk(KERN_ERR, EDAC_MC, "Failure initializing workqueue\n");
goto error; goto err_wq;
} }
return 0; return 0;
error: err_wq:
edac_debugfs_exit();
edac_mc_sysfs_exit();
err_sysfs:
return err; return err;
} }
......
...@@ -22,7 +22,8 @@ ...@@ -22,7 +22,8 @@
/* on edac_mc_sysfs.c */ /* on edac_mc_sysfs.c */
int edac_mc_sysfs_init(void); int edac_mc_sysfs_init(void);
void edac_mc_sysfs_exit(void); void edac_mc_sysfs_exit(void);
extern int edac_create_sysfs_mci_device(struct mem_ctl_info *mci); extern int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
const struct attribute_group **groups);
extern void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci); extern void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci);
void edac_unregister_sysfs(struct mem_ctl_info *mci); void edac_unregister_sysfs(struct mem_ctl_info *mci);
extern int edac_get_log_ue(void); extern int edac_get_log_ue(void);
......
...@@ -124,6 +124,13 @@ static ssize_t highbank_mc_inject_ctrl(struct device *dev, ...@@ -124,6 +124,13 @@ static ssize_t highbank_mc_inject_ctrl(struct device *dev,
static DEVICE_ATTR(inject_ctrl, S_IWUSR, NULL, highbank_mc_inject_ctrl); static DEVICE_ATTR(inject_ctrl, S_IWUSR, NULL, highbank_mc_inject_ctrl);
static struct attribute *highbank_dev_attrs[] = {
&dev_attr_inject_ctrl.attr,
NULL
};
ATTRIBUTE_GROUPS(highbank_dev);
struct hb_mc_settings { struct hb_mc_settings {
int err_offset; int err_offset;
int int_offset; int int_offset;
...@@ -139,7 +146,7 @@ static struct hb_mc_settings mw_settings = { ...@@ -139,7 +146,7 @@ static struct hb_mc_settings mw_settings = {
.int_offset = MW_DDR_ECC_INT_BASE, .int_offset = MW_DDR_ECC_INT_BASE,
}; };
static struct of_device_id hb_ddr_ctrl_of_match[] = { static const struct of_device_id hb_ddr_ctrl_of_match[] = {
{ .compatible = "calxeda,hb-ddr-ctrl", .data = &hb_settings }, { .compatible = "calxeda,hb-ddr-ctrl", .data = &hb_settings },
{ .compatible = "calxeda,ecx-2000-ddr-ctrl", .data = &mw_settings }, { .compatible = "calxeda,ecx-2000-ddr-ctrl", .data = &mw_settings },
{}, {},
...@@ -231,7 +238,7 @@ static int highbank_mc_probe(struct platform_device *pdev) ...@@ -231,7 +238,7 @@ static int highbank_mc_probe(struct platform_device *pdev)
dimm->mtype = MEM_DDR3; dimm->mtype = MEM_DDR3;
dimm->edac_mode = EDAC_SECDED; dimm->edac_mode = EDAC_SECDED;
res = edac_mc_add_mc(mci); res = edac_mc_add_mc_with_groups(mci, highbank_dev_groups);
if (res < 0) if (res < 0)
goto err; goto err;
...@@ -243,8 +250,6 @@ static int highbank_mc_probe(struct platform_device *pdev) ...@@ -243,8 +250,6 @@ static int highbank_mc_probe(struct platform_device *pdev)
goto err2; goto err2;
} }
device_create_file(&mci->dev, &dev_attr_inject_ctrl);
devres_close_group(&pdev->dev, NULL); devres_close_group(&pdev->dev, NULL);
return 0; return 0;
err2: err2:
...@@ -259,7 +264,6 @@ static int highbank_mc_remove(struct platform_device *pdev) ...@@ -259,7 +264,6 @@ static int highbank_mc_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
device_remove_file(&mci->dev, &dev_attr_inject_ctrl);
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0; return 0;
......
...@@ -1157,27 +1157,24 @@ static DEVICE_ATTR(inject_eccmask, S_IRUGO | S_IWUSR, ...@@ -1157,27 +1157,24 @@ static DEVICE_ATTR(inject_eccmask, S_IRUGO | S_IWUSR,
static DEVICE_ATTR(inject_enable, S_IRUGO | S_IWUSR, static DEVICE_ATTR(inject_enable, S_IRUGO | S_IWUSR,
i7core_inject_enable_show, i7core_inject_enable_store); i7core_inject_enable_show, i7core_inject_enable_store);
static struct attribute *i7core_dev_attrs[] = {
&dev_attr_inject_section.attr,
&dev_attr_inject_type.attr,
&dev_attr_inject_eccmask.attr,
&dev_attr_inject_enable.attr,
NULL
};
ATTRIBUTE_GROUPS(i7core_dev);
static int i7core_create_sysfs_devices(struct mem_ctl_info *mci) static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
{ {
struct i7core_pvt *pvt = mci->pvt_info; struct i7core_pvt *pvt = mci->pvt_info;
int rc; int rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_section);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_type);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_eccmask);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_enable);
if (rc < 0)
return rc;
pvt->addrmatch_dev = kzalloc(sizeof(*pvt->addrmatch_dev), GFP_KERNEL); pvt->addrmatch_dev = kzalloc(sizeof(*pvt->addrmatch_dev), GFP_KERNEL);
if (!pvt->addrmatch_dev) if (!pvt->addrmatch_dev)
return rc; return -ENOMEM;
pvt->addrmatch_dev->type = &addrmatch_type; pvt->addrmatch_dev->type = &addrmatch_type;
pvt->addrmatch_dev->bus = mci->dev.bus; pvt->addrmatch_dev->bus = mci->dev.bus;
...@@ -1198,7 +1195,7 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci) ...@@ -1198,7 +1195,7 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
if (!pvt->chancounts_dev) { if (!pvt->chancounts_dev) {
put_device(pvt->addrmatch_dev); put_device(pvt->addrmatch_dev);
device_del(pvt->addrmatch_dev); device_del(pvt->addrmatch_dev);
return rc; return -ENOMEM;
} }
pvt->chancounts_dev->type = &all_channel_counts_type; pvt->chancounts_dev->type = &all_channel_counts_type;
...@@ -1223,11 +1220,6 @@ static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci) ...@@ -1223,11 +1220,6 @@ static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
edac_dbg(1, "\n"); edac_dbg(1, "\n");
device_remove_file(&mci->dev, &dev_attr_inject_section);
device_remove_file(&mci->dev, &dev_attr_inject_type);
device_remove_file(&mci->dev, &dev_attr_inject_eccmask);
device_remove_file(&mci->dev, &dev_attr_inject_enable);
if (!pvt->is_registered) { if (!pvt->is_registered) {
put_device(pvt->chancounts_dev); put_device(pvt->chancounts_dev);
device_del(pvt->chancounts_dev); device_del(pvt->chancounts_dev);
...@@ -2259,7 +2251,7 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev) ...@@ -2259,7 +2251,7 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev)
enable_sdram_scrub_setting(mci); enable_sdram_scrub_setting(mci);
/* add this new MC control structure to EDAC's list of MCs */ /* add this new MC control structure to EDAC's list of MCs */
if (unlikely(edac_mc_add_mc(mci))) { if (unlikely(edac_mc_add_mc_with_groups(mci, i7core_dev_groups))) {
edac_dbg(0, "MC: failed edac_mc_add_mc()\n"); edac_dbg(0, "MC: failed edac_mc_add_mc()\n");
/* FIXME: perhaps some code should go here that disables error /* FIXME: perhaps some code should go here that disables error
* reporting if we just enabled it * reporting if we just enabled it
......
...@@ -350,8 +350,6 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -350,8 +350,6 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx)
return -ENODEV; return -ENODEV;
} }
EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_probe1);
/* returns count (>= 0), or negative on error */ /* returns count (>= 0), or negative on error */
static int i82443bxgx_edacmc_init_one(struct pci_dev *pdev, static int i82443bxgx_edacmc_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
...@@ -384,8 +382,6 @@ static void i82443bxgx_edacmc_remove_one(struct pci_dev *pdev) ...@@ -384,8 +382,6 @@ static void i82443bxgx_edacmc_remove_one(struct pci_dev *pdev)
edac_mc_free(mci); edac_mc_free(mci);
} }
EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_remove_one);
static const struct pci_device_id i82443bxgx_pci_tbl[] = { static const struct pci_device_id i82443bxgx_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2)},
...@@ -445,9 +441,7 @@ static int __init i82443bxgx_edacmc_init(void) ...@@ -445,9 +441,7 @@ static int __init i82443bxgx_edacmc_init(void)
pci_unregister_driver(&i82443bxgx_edacmc_driver); pci_unregister_driver(&i82443bxgx_edacmc_driver);
fail0: fail0:
if (mci_pdev != NULL) pci_dev_put(mci_pdev);
pci_dev_put(mci_pdev);
return pci_rc; return pci_rc;
} }
......
...@@ -343,20 +343,15 @@ static int __init i82860_init(void) ...@@ -343,20 +343,15 @@ static int __init i82860_init(void)
pci_unregister_driver(&i82860_driver); pci_unregister_driver(&i82860_driver);
fail0: fail0:
if (mci_pdev != NULL) pci_dev_put(mci_pdev);
pci_dev_put(mci_pdev);
return pci_rc; return pci_rc;
} }
static void __exit i82860_exit(void) static void __exit i82860_exit(void)
{ {
edac_dbg(3, "\n"); edac_dbg(3, "\n");
pci_unregister_driver(&i82860_driver); pci_unregister_driver(&i82860_driver);
pci_dev_put(mci_pdev);
if (mci_pdev != NULL)
pci_dev_put(mci_pdev);
} }
module_init(i82860_init); module_init(i82860_init);
......
...@@ -576,9 +576,7 @@ static int __init i82875p_init(void) ...@@ -576,9 +576,7 @@ static int __init i82875p_init(void)
pci_unregister_driver(&i82875p_driver); pci_unregister_driver(&i82875p_driver);
fail0: fail0:
if (mci_pdev != NULL) pci_dev_put(mci_pdev);
pci_dev_put(mci_pdev);
return pci_rc; return pci_rc;
} }
......
...@@ -685,9 +685,7 @@ static int __init i82975x_init(void) ...@@ -685,9 +685,7 @@ static int __init i82975x_init(void)
pci_unregister_driver(&i82975x_driver); pci_unregister_driver(&i82975x_driver);
fail0: fail0:
if (mci_pdev != NULL) pci_dev_put(mci_pdev);
pci_dev_put(mci_pdev);
return pci_rc; return pci_rc;
} }
......
...@@ -134,29 +134,14 @@ DEVICE_ATTR(inject_data_lo, S_IRUGO | S_IWUSR, ...@@ -134,29 +134,14 @@ DEVICE_ATTR(inject_data_lo, S_IRUGO | S_IWUSR,
DEVICE_ATTR(inject_ctrl, S_IRUGO | S_IWUSR, DEVICE_ATTR(inject_ctrl, S_IRUGO | S_IWUSR,
mpc85xx_mc_inject_ctrl_show, mpc85xx_mc_inject_ctrl_store); mpc85xx_mc_inject_ctrl_show, mpc85xx_mc_inject_ctrl_store);
static int mpc85xx_create_sysfs_attributes(struct mem_ctl_info *mci) static struct attribute *mpc85xx_dev_attrs[] = {
{ &dev_attr_inject_data_hi.attr,
int rc; &dev_attr_inject_data_lo.attr,
&dev_attr_inject_ctrl.attr,
rc = device_create_file(&mci->dev, &dev_attr_inject_data_hi); NULL
if (rc < 0) };
return rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_data_lo);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_inject_ctrl);
if (rc < 0)
return rc;
return 0; ATTRIBUTE_GROUPS(mpc85xx_dev);
}
static void mpc85xx_remove_sysfs_attributes(struct mem_ctl_info *mci)
{
device_remove_file(&mci->dev, &dev_attr_inject_data_hi);
device_remove_file(&mci->dev, &dev_attr_inject_data_lo);
device_remove_file(&mci->dev, &dev_attr_inject_ctrl);
}
/**************************** PCI Err device ***************************/ /**************************** PCI Err device ***************************/
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -685,7 +670,7 @@ static int mpc85xx_l2_err_remove(struct platform_device *op) ...@@ -685,7 +670,7 @@ static int mpc85xx_l2_err_remove(struct platform_device *op)
return 0; return 0;
} }
static struct of_device_id mpc85xx_l2_err_of_match[] = { static const struct of_device_id mpc85xx_l2_err_of_match[] = {
/* deprecate the fsl,85.. forms in the future, 2.6.30? */ /* deprecate the fsl,85.. forms in the future, 2.6.30? */
{ .compatible = "fsl,8540-l2-cache-controller", }, { .compatible = "fsl,8540-l2-cache-controller", },
{ .compatible = "fsl,8541-l2-cache-controller", }, { .compatible = "fsl,8541-l2-cache-controller", },
...@@ -1106,13 +1091,7 @@ static int mpc85xx_mc_err_probe(struct platform_device *op) ...@@ -1106,13 +1091,7 @@ static int mpc85xx_mc_err_probe(struct platform_device *op)
/* clear all error bits */ /* clear all error bits */
out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0); out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0);
if (edac_mc_add_mc(mci)) { if (edac_mc_add_mc_with_groups(mci, mpc85xx_dev_groups)) {
edac_dbg(3, "failed edac_mc_add_mc()\n");
goto err;
}
if (mpc85xx_create_sysfs_attributes(mci)) {
edac_mc_del_mc(mci->pdev);
edac_dbg(3, "failed edac_mc_add_mc()\n"); edac_dbg(3, "failed edac_mc_add_mc()\n");
goto err; goto err;
} }
...@@ -1176,13 +1155,12 @@ static int mpc85xx_mc_err_remove(struct platform_device *op) ...@@ -1176,13 +1155,12 @@ static int mpc85xx_mc_err_remove(struct platform_device *op)
orig_ddr_err_disable); orig_ddr_err_disable);
out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, orig_ddr_err_sbe); out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, orig_ddr_err_sbe);
mpc85xx_remove_sysfs_attributes(mci);
edac_mc_del_mc(&op->dev); edac_mc_del_mc(&op->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0; return 0;
} }
static struct of_device_id mpc85xx_mc_err_of_match[] = { static const struct of_device_id mpc85xx_mc_err_of_match[] = {
/* deprecate the fsl,85.. forms in the future, 2.6.30? */ /* deprecate the fsl,85.. forms in the future, 2.6.30? */
{ .compatible = "fsl,8540-memory-controller", }, { .compatible = "fsl,8540-memory-controller", },
{ .compatible = "fsl,8541-memory-controller", }, { .compatible = "fsl,8541-memory-controller", },
......
...@@ -209,35 +209,18 @@ static DEVICE_ATTR(row, S_IRUGO | S_IWUSR, ...@@ -209,35 +209,18 @@ static DEVICE_ATTR(row, S_IRUGO | S_IWUSR,
static DEVICE_ATTR(col, S_IRUGO | S_IWUSR, static DEVICE_ATTR(col, S_IRUGO | S_IWUSR,
octeon_mc_inject_col_show, octeon_mc_inject_col_store); octeon_mc_inject_col_show, octeon_mc_inject_col_store);
static struct attribute *octeon_dev_attrs[] = {
&dev_attr_inject.attr,
&dev_attr_error_type.attr,
&dev_attr_dimm.attr,
&dev_attr_rank.attr,
&dev_attr_bank.attr,
&dev_attr_row.attr,
&dev_attr_col.attr,
NULL
};
static int octeon_set_mc_sysfs_attributes(struct mem_ctl_info *mci) ATTRIBUTE_GROUPS(octeon_dev);
{
int rc;
rc = device_create_file(&mci->dev, &dev_attr_inject);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_error_type);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_dimm);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_rank);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_bank);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_row);
if (rc < 0)
return rc;
rc = device_create_file(&mci->dev, &dev_attr_col);
if (rc < 0)
return rc;
return 0;
}
static int octeon_lmc_edac_probe(struct platform_device *pdev) static int octeon_lmc_edac_probe(struct platform_device *pdev)
{ {
...@@ -271,18 +254,12 @@ static int octeon_lmc_edac_probe(struct platform_device *pdev) ...@@ -271,18 +254,12 @@ static int octeon_lmc_edac_probe(struct platform_device *pdev)
mci->ctl_name = "octeon-lmc-err"; mci->ctl_name = "octeon-lmc-err";
mci->edac_check = octeon_lmc_edac_poll; mci->edac_check = octeon_lmc_edac_poll;
if (edac_mc_add_mc(mci)) { if (edac_mc_add_mc_with_groups(mci, octeon_dev_groups)) {
dev_err(&pdev->dev, "edac_mc_add_mc() failed\n"); dev_err(&pdev->dev, "edac_mc_add_mc() failed\n");
edac_mc_free(mci); edac_mc_free(mci);
return -ENXIO; return -ENXIO;
} }
if (octeon_set_mc_sysfs_attributes(mci)) {
dev_err(&pdev->dev, "octeon_set_mc_sysfs_attributes() failed\n");
return -ENXIO;
}
cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc)); cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc));
cfg0.s.intr_ded_ena = 0; /* We poll */ cfg0.s.intr_ded_ena = 0; /* We poll */
cfg0.s.intr_sec_ena = 0; cfg0.s.intr_sec_ena = 0;
...@@ -309,18 +286,12 @@ static int octeon_lmc_edac_probe(struct platform_device *pdev) ...@@ -309,18 +286,12 @@ static int octeon_lmc_edac_probe(struct platform_device *pdev)
mci->ctl_name = "co_lmc_err"; mci->ctl_name = "co_lmc_err";
mci->edac_check = octeon_lmc_edac_poll_o2; mci->edac_check = octeon_lmc_edac_poll_o2;
if (edac_mc_add_mc(mci)) { if (edac_mc_add_mc_with_groups(mci, octeon_dev_groups)) {
dev_err(&pdev->dev, "edac_mc_add_mc() failed\n"); dev_err(&pdev->dev, "edac_mc_add_mc() failed\n");
edac_mc_free(mci); edac_mc_free(mci);
return -ENXIO; return -ENXIO;
} }
if (octeon_set_mc_sysfs_attributes(mci)) {
dev_err(&pdev->dev, "octeon_set_mc_sysfs_attributes() failed\n");
return -ENXIO;
}
en.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc)); en.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc));
en.s.intr_ded_ena = 0; /* We poll */ en.s.intr_ded_ena = 0; /* We poll */
en.s.intr_sec_ena = 0; en.s.intr_sec_ena = 0;
......
...@@ -193,7 +193,7 @@ static int ppc4xx_edac_remove(struct platform_device *device); ...@@ -193,7 +193,7 @@ static int ppc4xx_edac_remove(struct platform_device *device);
* Device tree node type and compatible tuples this driver can match * Device tree node type and compatible tuples this driver can match
* on. * on.
*/ */
static struct of_device_id ppc4xx_edac_match[] = { static const struct of_device_id ppc4xx_edac_match[] = {
{ {
.compatible = "ibm,sdram-4xx-ddr2" .compatible = "ibm,sdram-4xx-ddr2"
}, },
......
...@@ -512,7 +512,7 @@ static int synps_edac_mc_remove(struct platform_device *pdev) ...@@ -512,7 +512,7 @@ static int synps_edac_mc_remove(struct platform_device *pdev)
return 0; return 0;
} }
static struct of_device_id synps_edac_match[] = { static const struct of_device_id synps_edac_match[] = {
{ .compatible = "xlnx,zynq-ddrc-a05", }, { .compatible = "xlnx,zynq-ddrc-a05", },
{ /* end of table */ } { /* end of table */ }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment