aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 17:47:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 17:47:37 -0400
commit1a370f4cd95e056d55ef5bf1a183880e70195e59 (patch)
treec672eb30748d56e7d0df41a0dec7d59c8b65e25a
parent4b5ca74113a1e02f4a7ea80aea9b977705f3d961 (diff)
parent1afaa05515212b136d96a48b2ba2251f40437d87 (diff)
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()
-rw-r--r--drivers/edac/amd64_edac.c80
-rw-r--r--drivers/edac/amd64_edac.h24
-rw-r--r--drivers/edac/amd64_edac_dbg.c43
-rw-r--r--drivers/edac/amd64_edac_inj.c51
-rw-r--r--drivers/edac/edac_core.h4
-rw-r--r--drivers/edac/edac_mc.c12
-rw-r--r--drivers/edac/edac_mc_sysfs.c167
-rw-r--r--drivers/edac/edac_module.c13
-rw-r--r--drivers/edac/edac_module.h3
-rw-r--r--drivers/edac/highbank_mc_edac.c14
-rw-r--r--drivers/edac/i7core_edac.c34
-rw-r--r--drivers/edac/i82443bxgx_edac.c8
-rw-r--r--drivers/edac/i82860_edac.c9
-rw-r--r--drivers/edac/i82875p_edac.c4
-rw-r--r--drivers/edac/i82975x_edac.c4
-rw-r--r--drivers/edac/mpc85xx_edac.c42
-rw-r--r--drivers/edac/octeon_edac-lmc.c55
-rw-r--r--drivers/edac/ppc4xx_edac.c2
-rw-r--r--drivers/edac/synopsys_edac.c2
19 files changed, 208 insertions, 363 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 5907c1718f8c..92772fffc52f 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -20,8 +20,7 @@ static struct msr __percpu *msrs;
20 */ 20 */
21static atomic_t drv_instances = ATOMIC_INIT(0); 21static atomic_t drv_instances = ATOMIC_INIT(0);
22 22
23/* Per-node driver instances */ 23/* Per-node stuff */
24static struct mem_ctl_info **mcis;
25static struct ecc_settings **ecc_stngs; 24static struct ecc_settings **ecc_stngs;
26 25
27/* 26/*
@@ -903,9 +902,17 @@ static int k8_early_channel_count(struct amd64_pvt *pvt)
903/* On F10h and later ErrAddr is MC4_ADDR[47:1] */ 902/* On F10h and later ErrAddr is MC4_ADDR[47:1] */
904static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m) 903static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m)
905{ 904{
906 u64 addr; 905 u16 mce_nid = amd_get_nb_id(m->extcpu);
906 struct mem_ctl_info *mci;
907 u8 start_bit = 1; 907 u8 start_bit = 1;
908 u8 end_bit = 47; 908 u8 end_bit = 47;
909 u64 addr;
910
911 mci = edac_mc_find(mce_nid);
912 if (!mci)
913 return 0;
914
915 pvt = mci->pvt_info;
909 916
910 if (pvt->fam == 0xf) { 917 if (pvt->fam == 0xf) {
911 start_bit = 3; 918 start_bit = 3;
@@ -918,17 +925,13 @@ static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m)
918 * Erratum 637 workaround 925 * Erratum 637 workaround
919 */ 926 */
920 if (pvt->fam == 0x15) { 927 if (pvt->fam == 0x15) {
921 struct amd64_pvt *pvt;
922 u64 cc6_base, tmp_addr; 928 u64 cc6_base, tmp_addr;
923 u32 tmp; 929 u32 tmp;
924 u16 mce_nid;
925 u8 intlv_en; 930 u8 intlv_en;
926 931
927 if ((addr & GENMASK_ULL(47, 24)) >> 24 != 0x00fdf7) 932 if ((addr & GENMASK_ULL(47, 24)) >> 24 != 0x00fdf7)
928 return addr; 933 return addr;
929 934
930 mce_nid = amd_get_nb_id(m->extcpu);
931 pvt = mcis[mce_nid]->pvt_info;
932 935
933 amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_LIM, &tmp); 936 amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_LIM, &tmp);
934 intlv_en = tmp >> 21 & 0x7; 937 intlv_en = tmp >> 21 & 0x7;
@@ -1511,7 +1514,7 @@ static int f1x_lookup_addr_in_dct(u64 in_addr, u8 nid, u8 dct)
1511 int cs_found = -EINVAL; 1514 int cs_found = -EINVAL;
1512 int csrow; 1515 int csrow;
1513 1516
1514 mci = mcis[nid]; 1517 mci = edac_mc_find(nid);
1515 if (!mci) 1518 if (!mci)
1516 return cs_found; 1519 return cs_found;
1517 1520
@@ -2663,34 +2666,6 @@ static bool ecc_enabled(struct pci_dev *F3, u16 nid)
2663 return true; 2666 return true;
2664} 2667}
2665 2668
2666static int set_mc_sysfs_attrs(struct mem_ctl_info *mci)
2667{
2668 struct amd64_pvt *pvt = mci->pvt_info;
2669 int rc;
2670
2671 rc = amd64_create_sysfs_dbg_files(mci);
2672 if (rc < 0)
2673 return rc;
2674
2675 if (pvt->fam >= 0x10) {
2676 rc = amd64_create_sysfs_inject_files(mci);
2677 if (rc < 0)
2678 return rc;
2679 }
2680
2681 return 0;
2682}
2683
2684static void del_mc_sysfs_attrs(struct mem_ctl_info *mci)
2685{
2686 struct amd64_pvt *pvt = mci->pvt_info;
2687
2688 amd64_remove_sysfs_dbg_files(mci);
2689
2690 if (pvt->fam >= 0x10)
2691 amd64_remove_sysfs_inject_files(mci);
2692}
2693
2694static void setup_mci_misc_attrs(struct mem_ctl_info *mci, 2669static void setup_mci_misc_attrs(struct mem_ctl_info *mci,
2695 struct amd64_family_type *fam) 2670 struct amd64_family_type *fam)
2696{ 2671{
@@ -2778,6 +2753,16 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt)
2778 return fam_type; 2753 return fam_type;
2779} 2754}
2780 2755
2756static const struct attribute_group *amd64_edac_attr_groups[] = {
2757#ifdef CONFIG_EDAC_DEBUG
2758 &amd64_edac_dbg_group,
2759#endif
2760#ifdef CONFIG_EDAC_AMD64_ERROR_INJECTION
2761 &amd64_edac_inj_group,
2762#endif
2763 NULL
2764};
2765
2781static int init_one_instance(struct pci_dev *F2) 2766static int init_one_instance(struct pci_dev *F2)
2782{ 2767{
2783 struct amd64_pvt *pvt = NULL; 2768 struct amd64_pvt *pvt = NULL;
@@ -2844,14 +2829,10 @@ static int init_one_instance(struct pci_dev *F2)
2844 mci->edac_cap = EDAC_FLAG_NONE; 2829 mci->edac_cap = EDAC_FLAG_NONE;
2845 2830
2846 ret = -ENODEV; 2831 ret = -ENODEV;
2847 if (edac_mc_add_mc(mci)) { 2832 if (edac_mc_add_mc_with_groups(mci, amd64_edac_attr_groups)) {
2848 edac_dbg(1, "failed edac_mc_add_mc()\n"); 2833 edac_dbg(1, "failed edac_mc_add_mc()\n");
2849 goto err_add_mc; 2834 goto err_add_mc;
2850 } 2835 }
2851 if (set_mc_sysfs_attrs(mci)) {
2852 edac_dbg(1, "failed edac_mc_add_mc()\n");
2853 goto err_add_sysfs;
2854 }
2855 2836
2856 /* register stuff with EDAC MCE */ 2837 /* register stuff with EDAC MCE */
2857 if (report_gart_errors) 2838 if (report_gart_errors)
@@ -2859,14 +2840,10 @@ static int init_one_instance(struct pci_dev *F2)
2859 2840
2860 amd_register_ecc_decoder(decode_bus_error); 2841 amd_register_ecc_decoder(decode_bus_error);
2861 2842
2862 mcis[nid] = mci;
2863
2864 atomic_inc(&drv_instances); 2843 atomic_inc(&drv_instances);
2865 2844
2866 return 0; 2845 return 0;
2867 2846
2868err_add_sysfs:
2869 edac_mc_del_mc(mci->pdev);
2870err_add_mc: 2847err_add_mc:
2871 edac_mc_free(mci); 2848 edac_mc_free(mci);
2872 2849
@@ -2940,7 +2917,6 @@ static void remove_one_instance(struct pci_dev *pdev)
2940 mci = find_mci_by_dev(&pdev->dev); 2917 mci = find_mci_by_dev(&pdev->dev);
2941 WARN_ON(!mci); 2918 WARN_ON(!mci);
2942 2919
2943 del_mc_sysfs_attrs(mci);
2944 /* Remove from EDAC CORE tracking list */ 2920 /* Remove from EDAC CORE tracking list */
2945 mci = edac_mc_del_mc(&pdev->dev); 2921 mci = edac_mc_del_mc(&pdev->dev);
2946 if (!mci) 2922 if (!mci)
@@ -2961,7 +2937,6 @@ static void remove_one_instance(struct pci_dev *pdev)
2961 2937
2962 /* Free the EDAC CORE resources */ 2938 /* Free the EDAC CORE resources */
2963 mci->pvt_info = NULL; 2939 mci->pvt_info = NULL;
2964 mcis[nid] = NULL;
2965 2940
2966 kfree(pvt); 2941 kfree(pvt);
2967 edac_mc_free(mci); 2942 edac_mc_free(mci);
@@ -2999,7 +2974,7 @@ static void setup_pci_device(void)
2999 if (pci_ctl) 2974 if (pci_ctl)
3000 return; 2975 return;
3001 2976
3002 mci = mcis[0]; 2977 mci = edac_mc_find(0);
3003 if (!mci) 2978 if (!mci)
3004 return; 2979 return;
3005 2980
@@ -3023,9 +2998,8 @@ static int __init amd64_edac_init(void)
3023 goto err_ret; 2998 goto err_ret;
3024 2999
3025 err = -ENOMEM; 3000 err = -ENOMEM;
3026 mcis = kzalloc(amd_nb_num() * sizeof(mcis[0]), GFP_KERNEL);
3027 ecc_stngs = kzalloc(amd_nb_num() * sizeof(ecc_stngs[0]), GFP_KERNEL); 3001 ecc_stngs = kzalloc(amd_nb_num() * sizeof(ecc_stngs[0]), GFP_KERNEL);
3028 if (!(mcis && ecc_stngs)) 3002 if (!ecc_stngs)
3029 goto err_free; 3003 goto err_free;
3030 3004
3031 msrs = msrs_alloc(); 3005 msrs = msrs_alloc();
@@ -3056,9 +3030,6 @@ err_pci:
3056 msrs = NULL; 3030 msrs = NULL;
3057 3031
3058err_free: 3032err_free:
3059 kfree(mcis);
3060 mcis = NULL;
3061
3062 kfree(ecc_stngs); 3033 kfree(ecc_stngs);
3063 ecc_stngs = NULL; 3034 ecc_stngs = NULL;
3064 3035
@@ -3076,9 +3047,6 @@ static void __exit amd64_edac_exit(void)
3076 kfree(ecc_stngs); 3047 kfree(ecc_stngs);
3077 ecc_stngs = NULL; 3048 ecc_stngs = NULL;
3078 3049
3079 kfree(mcis);
3080 mcis = NULL;
3081
3082 msrs_free(msrs); 3050 msrs_free(msrs);
3083 msrs = NULL; 3051 msrs = NULL;
3084} 3052}
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index d8468c667925..4bdec752d330 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -453,31 +453,11 @@ struct ecc_settings {
453}; 453};
454 454
455#ifdef CONFIG_EDAC_DEBUG 455#ifdef CONFIG_EDAC_DEBUG
456int amd64_create_sysfs_dbg_files(struct mem_ctl_info *mci); 456extern const struct attribute_group amd64_edac_dbg_group;
457void amd64_remove_sysfs_dbg_files(struct mem_ctl_info *mci);
458
459#else
460static inline int amd64_create_sysfs_dbg_files(struct mem_ctl_info *mci)
461{
462 return 0;
463}
464static void inline amd64_remove_sysfs_dbg_files(struct mem_ctl_info *mci)
465{
466}
467#endif 457#endif
468 458
469#ifdef CONFIG_EDAC_AMD64_ERROR_INJECTION 459#ifdef CONFIG_EDAC_AMD64_ERROR_INJECTION
470int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci); 460extern const struct attribute_group amd64_edac_inj_group;
471void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci);
472
473#else
474static inline int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci)
475{
476 return 0;
477}
478static inline void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci)
479{
480}
481#endif 461#endif
482 462
483/* 463/*
diff --git a/drivers/edac/amd64_edac_dbg.c b/drivers/edac/amd64_edac_dbg.c
index 2c1bbf740605..4709c6079848 100644
--- a/drivers/edac/amd64_edac_dbg.c
+++ b/drivers/edac/amd64_edac_dbg.c
@@ -40,34 +40,15 @@ static DEVICE_ATTR(topmem, S_IRUGO, amd64_top_mem_show, NULL);
40static DEVICE_ATTR(topmem2, S_IRUGO, amd64_top_mem2_show, NULL); 40static DEVICE_ATTR(topmem2, S_IRUGO, amd64_top_mem2_show, NULL);
41static DEVICE_ATTR(dram_hole, S_IRUGO, amd64_hole_show, NULL); 41static DEVICE_ATTR(dram_hole, S_IRUGO, amd64_hole_show, NULL);
42 42
43int amd64_create_sysfs_dbg_files(struct mem_ctl_info *mci) 43static struct attribute *amd64_edac_dbg_attrs[] = {
44{ 44 &dev_attr_dhar.attr,
45 int rc; 45 &dev_attr_dbam.attr,
46 46 &dev_attr_topmem.attr,
47 rc = device_create_file(&mci->dev, &dev_attr_dhar); 47 &dev_attr_topmem2.attr,
48 if (rc < 0) 48 &dev_attr_dram_hole.attr,
49 return rc; 49 NULL
50 rc = device_create_file(&mci->dev, &dev_attr_dbam); 50};
51 if (rc < 0) 51
52 return rc; 52const struct attribute_group amd64_edac_dbg_group = {
53 rc = device_create_file(&mci->dev, &dev_attr_topmem); 53 .attrs = amd64_edac_dbg_attrs,
54 if (rc < 0) 54};
55 return rc;
56 rc = device_create_file(&mci->dev, &dev_attr_topmem2);
57 if (rc < 0)
58 return rc;
59 rc = device_create_file(&mci->dev, &dev_attr_dram_hole);
60 if (rc < 0)
61 return rc;
62
63 return 0;
64}
65
66void amd64_remove_sysfs_dbg_files(struct mem_ctl_info *mci)
67{
68 device_remove_file(&mci->dev, &dev_attr_dhar);
69 device_remove_file(&mci->dev, &dev_attr_dbam);
70 device_remove_file(&mci->dev, &dev_attr_topmem);
71 device_remove_file(&mci->dev, &dev_attr_topmem2);
72 device_remove_file(&mci->dev, &dev_attr_dram_hole);
73}
diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c
index 0d66ae68d468..e14977ff95db 100644
--- a/drivers/edac/amd64_edac_inj.c
+++ b/drivers/edac/amd64_edac_inj.c
@@ -207,35 +207,28 @@ static DEVICE_ATTR(inject_write, S_IWUSR,
207static DEVICE_ATTR(inject_read, S_IWUSR, 207static DEVICE_ATTR(inject_read, S_IWUSR,
208 NULL, amd64_inject_read_store); 208 NULL, amd64_inject_read_store);
209 209
210 210static struct attribute *amd64_edac_inj_attrs[] = {
211int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci) 211 &dev_attr_inject_section.attr,
212 &dev_attr_inject_word.attr,
213 &dev_attr_inject_ecc_vector.attr,
214 &dev_attr_inject_write.attr,
215 &dev_attr_inject_read.attr,
216 NULL
217};
218
219static umode_t amd64_edac_inj_is_visible(struct kobject *kobj,
220 struct attribute *attr, int idx)
212{ 221{
213 int rc; 222 struct device *dev = kobj_to_dev(kobj);
214 223 struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev);
215 rc = device_create_file(&mci->dev, &dev_attr_inject_section); 224 struct amd64_pvt *pvt = mci->pvt_info;
216 if (rc < 0)
217 return rc;
218 rc = device_create_file(&mci->dev, &dev_attr_inject_word);
219 if (rc < 0)
220 return rc;
221 rc = device_create_file(&mci->dev, &dev_attr_inject_ecc_vector);
222 if (rc < 0)
223 return rc;
224 rc = device_create_file(&mci->dev, &dev_attr_inject_write);
225 if (rc < 0)
226 return rc;
227 rc = device_create_file(&mci->dev, &dev_attr_inject_read);
228 if (rc < 0)
229 return rc;
230
231 return 0;
232}
233 225
234void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci) 226 if (pvt->fam < 0x10)
235{ 227 return 0;
236 device_remove_file(&mci->dev, &dev_attr_inject_section); 228 return attr->mode;
237 device_remove_file(&mci->dev, &dev_attr_inject_word);
238 device_remove_file(&mci->dev, &dev_attr_inject_ecc_vector);
239 device_remove_file(&mci->dev, &dev_attr_inject_write);
240 device_remove_file(&mci->dev, &dev_attr_inject_read);
241} 229}
230
231const struct attribute_group amd64_edac_inj_group = {
232 .attrs = amd64_edac_inj_attrs,
233 .is_visible = amd64_edac_inj_is_visible,
234};
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 6c9f381e8fe6..ad42587c3f4d 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -446,7 +446,9 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
446 unsigned n_layers, 446 unsigned n_layers,
447 struct edac_mc_layer *layers, 447 struct edac_mc_layer *layers,
448 unsigned sz_pvt); 448 unsigned sz_pvt);
449extern int edac_mc_add_mc(struct mem_ctl_info *mci); 449extern int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
450 const struct attribute_group **groups);
451#define edac_mc_add_mc(mci) edac_mc_add_mc_with_groups(mci, NULL)
450extern void edac_mc_free(struct mem_ctl_info *mci); 452extern void edac_mc_free(struct mem_ctl_info *mci);
451extern struct mem_ctl_info *edac_mc_find(int idx); 453extern struct mem_ctl_info *edac_mc_find(int idx);
452extern struct mem_ctl_info *find_mci_by_dev(struct device *dev); 454extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 1747906f10ce..af3be1914dbb 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -710,9 +710,10 @@ struct mem_ctl_info *edac_mc_find(int idx)
710EXPORT_SYMBOL(edac_mc_find); 710EXPORT_SYMBOL(edac_mc_find);
711 711
712/** 712/**
713 * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and 713 * edac_mc_add_mc_with_groups: Insert the 'mci' structure into the mci
714 * create sysfs entries associated with mci structure 714 * global list and create sysfs entries associated with mci structure
715 * @mci: pointer to the mci structure to be added to the list 715 * @mci: pointer to the mci structure to be added to the list
716 * @groups: optional attribute groups for the driver-specific sysfs entries
716 * 717 *
717 * Return: 718 * Return:
718 * 0 Success 719 * 0 Success
@@ -720,7 +721,8 @@ EXPORT_SYMBOL(edac_mc_find);
720 */ 721 */
721 722
722/* FIXME - should a warning be printed if no error detection? correction? */ 723/* FIXME - should a warning be printed if no error detection? correction? */
723int edac_mc_add_mc(struct mem_ctl_info *mci) 724int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
725 const struct attribute_group **groups)
724{ 726{
725 int ret = -EINVAL; 727 int ret = -EINVAL;
726 edac_dbg(0, "\n"); 728 edac_dbg(0, "\n");
@@ -771,7 +773,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
771 773
772 mci->bus = &mc_bus[mci->mc_idx]; 774 mci->bus = &mc_bus[mci->mc_idx];
773 775
774 if (edac_create_sysfs_mci_device(mci)) { 776 if (edac_create_sysfs_mci_device(mci, groups)) {
775 edac_mc_printk(mci, KERN_WARNING, 777 edac_mc_printk(mci, KERN_WARNING,
776 "failed to create sysfs device\n"); 778 "failed to create sysfs device\n");
777 goto fail1; 779 goto fail1;
@@ -805,7 +807,7 @@ fail0:
805 mutex_unlock(&mem_ctls_mutex); 807 mutex_unlock(&mem_ctls_mutex);
806 return ret; 808 return ret;
807} 809}
808EXPORT_SYMBOL_GPL(edac_mc_add_mc); 810EXPORT_SYMBOL_GPL(edac_mc_add_mc_with_groups);
809 811
810/** 812/**
811 * edac_mc_del_mc: Remove sysfs entries for specified mci structure and 813 * edac_mc_del_mc: Remove sysfs entries for specified mci structure and
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index c84eecb191ef..112d63ad1154 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -323,13 +323,14 @@ DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR,
323 channel_dimm_label_show, channel_dimm_label_store, 5); 323 channel_dimm_label_show, channel_dimm_label_store, 5);
324 324
325/* Total possible dynamic DIMM Label attribute file table */ 325/* Total possible dynamic DIMM Label attribute file table */
326static struct device_attribute *dynamic_csrow_dimm_attr[] = { 326static struct attribute *dynamic_csrow_dimm_attr[] = {
327 &dev_attr_legacy_ch0_dimm_label.attr, 327 &dev_attr_legacy_ch0_dimm_label.attr.attr,
328 &dev_attr_legacy_ch1_dimm_label.attr, 328 &dev_attr_legacy_ch1_dimm_label.attr.attr,
329 &dev_attr_legacy_ch2_dimm_label.attr, 329 &dev_attr_legacy_ch2_dimm_label.attr.attr,
330 &dev_attr_legacy_ch3_dimm_label.attr, 330 &dev_attr_legacy_ch3_dimm_label.attr.attr,
331 &dev_attr_legacy_ch4_dimm_label.attr, 331 &dev_attr_legacy_ch4_dimm_label.attr.attr,
332 &dev_attr_legacy_ch5_dimm_label.attr 332 &dev_attr_legacy_ch5_dimm_label.attr.attr,
333 NULL
333}; 334};
334 335
335/* possible dynamic channel ce_count attribute files */ 336/* possible dynamic channel ce_count attribute files */
@@ -347,13 +348,45 @@ DEVICE_CHANNEL(ch5_ce_count, S_IRUGO,
347 channel_ce_count_show, NULL, 5); 348 channel_ce_count_show, NULL, 5);
348 349
349/* Total possible dynamic ce_count attribute file table */ 350/* Total possible dynamic ce_count attribute file table */
350static struct device_attribute *dynamic_csrow_ce_count_attr[] = { 351static struct attribute *dynamic_csrow_ce_count_attr[] = {
351 &dev_attr_legacy_ch0_ce_count.attr, 352 &dev_attr_legacy_ch0_ce_count.attr.attr,
352 &dev_attr_legacy_ch1_ce_count.attr, 353 &dev_attr_legacy_ch1_ce_count.attr.attr,
353 &dev_attr_legacy_ch2_ce_count.attr, 354 &dev_attr_legacy_ch2_ce_count.attr.attr,
354 &dev_attr_legacy_ch3_ce_count.attr, 355 &dev_attr_legacy_ch3_ce_count.attr.attr,
355 &dev_attr_legacy_ch4_ce_count.attr, 356 &dev_attr_legacy_ch4_ce_count.attr.attr,
356 &dev_attr_legacy_ch5_ce_count.attr 357 &dev_attr_legacy_ch5_ce_count.attr.attr,
358 NULL
359};
360
361static umode_t csrow_dev_is_visible(struct kobject *kobj,
362 struct attribute *attr, int idx)
363{
364 struct device *dev = kobj_to_dev(kobj);
365 struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);
366
367 if (idx >= csrow->nr_channels)
368 return 0;
369 /* Only expose populated DIMMs */
370 if (!csrow->channels[idx]->dimm->nr_pages)
371 return 0;
372 return attr->mode;
373}
374
375
376static const struct attribute_group csrow_dev_dimm_group = {
377 .attrs = dynamic_csrow_dimm_attr,
378 .is_visible = csrow_dev_is_visible,
379};
380
381static const struct attribute_group csrow_dev_ce_count_group = {
382 .attrs = dynamic_csrow_ce_count_attr,
383 .is_visible = csrow_dev_is_visible,
384};
385
386static const struct attribute_group *csrow_dev_groups[] = {
387 &csrow_dev_dimm_group,
388 &csrow_dev_ce_count_group,
389 NULL
357}; 390};
358 391
359static inline int nr_pages_per_csrow(struct csrow_info *csrow) 392static 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)
370static int edac_create_csrow_object(struct mem_ctl_info *mci, 403static int edac_create_csrow_object(struct mem_ctl_info *mci,
371 struct csrow_info *csrow, int index) 404 struct csrow_info *csrow, int index)
372{ 405{
373 int err, chan;
374
375 if (csrow->nr_channels > EDAC_NR_CHANNELS) 406 if (csrow->nr_channels > EDAC_NR_CHANNELS)
376 return -ENODEV; 407 return -ENODEV;
377 408
378 csrow->dev.type = &csrow_attr_type; 409 csrow->dev.type = &csrow_attr_type;
379 csrow->dev.bus = mci->bus; 410 csrow->dev.bus = mci->bus;
411 csrow->dev.groups = csrow_dev_groups;
380 device_initialize(&csrow->dev); 412 device_initialize(&csrow->dev);
381 csrow->dev.parent = &mci->dev; 413 csrow->dev.parent = &mci->dev;
382 csrow->mci = mci; 414 csrow->mci = mci;
@@ -386,45 +418,13 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
386 edac_dbg(0, "creating (virtual) csrow node %s\n", 418 edac_dbg(0, "creating (virtual) csrow node %s\n",
387 dev_name(&csrow->dev)); 419 dev_name(&csrow->dev));
388 420
389 err = device_add(&csrow->dev); 421 return device_add(&csrow->dev);
390 if (err < 0)
391 return err;
392
393 for (chan = 0; chan < csrow->nr_channels; chan++) {
394 /* Only expose populated DIMMs */
395 if (!csrow->channels[chan]->dimm->nr_pages)
396 continue;
397 err = device_create_file(&csrow->dev,
398 dynamic_csrow_dimm_attr[chan]);
399 if (err < 0)
400 goto error;
401 err = device_create_file(&csrow->dev,
402 dynamic_csrow_ce_count_attr[chan]);
403 if (err < 0) {
404 device_remove_file(&csrow->dev,
405 dynamic_csrow_dimm_attr[chan]);
406 goto error;
407 }
408 }
409
410 return 0;
411
412error:
413 for (--chan; chan >= 0; chan--) {
414 device_remove_file(&csrow->dev,
415 dynamic_csrow_dimm_attr[chan]);
416 device_remove_file(&csrow->dev,
417 dynamic_csrow_ce_count_attr[chan]);
418 }
419 put_device(&csrow->dev);
420
421 return err;
422} 422}
423 423
424/* Create a CSROW object under specifed edac_mc_device */ 424/* Create a CSROW object under specifed edac_mc_device */
425static int edac_create_csrow_objects(struct mem_ctl_info *mci) 425static int edac_create_csrow_objects(struct mem_ctl_info *mci)
426{ 426{
427 int err, i, chan; 427 int err, i;
428 struct csrow_info *csrow; 428 struct csrow_info *csrow;
429 429
430 for (i = 0; i < mci->nr_csrows; i++) { 430 for (i = 0; i < mci->nr_csrows; i++) {
@@ -446,14 +446,6 @@ error:
446 csrow = mci->csrows[i]; 446 csrow = mci->csrows[i];
447 if (!nr_pages_per_csrow(csrow)) 447 if (!nr_pages_per_csrow(csrow))
448 continue; 448 continue;
449 for (chan = csrow->nr_channels - 1; chan >= 0; chan--) {
450 if (!csrow->channels[chan]->dimm->nr_pages)
451 continue;
452 device_remove_file(&csrow->dev,
453 dynamic_csrow_dimm_attr[chan]);
454 device_remove_file(&csrow->dev,
455 dynamic_csrow_ce_count_attr[chan]);
456 }
457 put_device(&mci->csrows[i]->dev); 449 put_device(&mci->csrows[i]->dev);
458 } 450 }
459 451
@@ -462,23 +454,13 @@ error:
462 454
463static void edac_delete_csrow_objects(struct mem_ctl_info *mci) 455static void edac_delete_csrow_objects(struct mem_ctl_info *mci)
464{ 456{
465 int i, chan; 457 int i;
466 struct csrow_info *csrow; 458 struct csrow_info *csrow;
467 459
468 for (i = mci->nr_csrows - 1; i >= 0; i--) { 460 for (i = mci->nr_csrows - 1; i >= 0; i--) {
469 csrow = mci->csrows[i]; 461 csrow = mci->csrows[i];
470 if (!nr_pages_per_csrow(csrow)) 462 if (!nr_pages_per_csrow(csrow))
471 continue; 463 continue;
472 for (chan = csrow->nr_channels - 1; chan >= 0; chan--) {
473 if (!csrow->channels[chan]->dimm->nr_pages)
474 continue;
475 edac_dbg(1, "Removing csrow %d channel %d sysfs nodes\n",
476 i, chan);
477 device_remove_file(&csrow->dev,
478 dynamic_csrow_dimm_attr[chan]);
479 device_remove_file(&csrow->dev,
480 dynamic_csrow_ce_count_attr[chan]);
481 }
482 device_unregister(&mci->csrows[i]->dev); 464 device_unregister(&mci->csrows[i]->dev);
483 } 465 }
484} 466}
@@ -863,7 +845,8 @@ static DEVICE_ATTR(ce_count, S_IRUGO, mci_ce_count_show, NULL);
863static DEVICE_ATTR(max_location, S_IRUGO, mci_max_location_show, NULL); 845static DEVICE_ATTR(max_location, S_IRUGO, mci_max_location_show, NULL);
864 846
865/* memory scrubber attribute file */ 847/* memory scrubber attribute file */
866static DEVICE_ATTR(sdram_scrub_rate, 0, NULL, NULL); 848DEVICE_ATTR(sdram_scrub_rate, 0, mci_sdram_scrub_rate_show,
849 mci_sdram_scrub_rate_store); /* umode set later in is_visible */
867 850
868static struct attribute *mci_attrs[] = { 851static struct attribute *mci_attrs[] = {
869 &dev_attr_reset_counters.attr, 852 &dev_attr_reset_counters.attr,
@@ -875,11 +858,29 @@ static struct attribute *mci_attrs[] = {
875 &dev_attr_ue_count.attr, 858 &dev_attr_ue_count.attr,
876 &dev_attr_ce_count.attr, 859 &dev_attr_ce_count.attr,
877 &dev_attr_max_location.attr, 860 &dev_attr_max_location.attr,
861 &dev_attr_sdram_scrub_rate.attr,
878 NULL 862 NULL
879}; 863};
880 864
865static umode_t mci_attr_is_visible(struct kobject *kobj,
866 struct attribute *attr, int idx)
867{
868 struct device *dev = kobj_to_dev(kobj);
869 struct mem_ctl_info *mci = to_mci(dev);
870 umode_t mode = 0;
871
872 if (attr != &dev_attr_sdram_scrub_rate.attr)
873 return attr->mode;
874 if (mci->get_sdram_scrub_rate)
875 mode |= S_IRUGO;
876 if (mci->set_sdram_scrub_rate)
877 mode |= S_IWUSR;
878 return mode;
879}
880
881static struct attribute_group mci_attr_grp = { 881static struct attribute_group mci_attr_grp = {
882 .attrs = mci_attrs, 882 .attrs = mci_attrs,
883 .is_visible = mci_attr_is_visible,
883}; 884};
884 885
885static const struct attribute_group *mci_attr_groups[] = { 886static const struct attribute_group *mci_attr_groups[] = {
@@ -913,7 +914,7 @@ int __init edac_debugfs_init(void)
913 return 0; 914 return 0;
914} 915}
915 916
916void __exit edac_debugfs_exit(void) 917void edac_debugfs_exit(void)
917{ 918{
918 debugfs_remove(edac_debugfs); 919 debugfs_remove(edac_debugfs);
919} 920}
@@ -973,7 +974,8 @@ nomem:
973 * 0 Success 974 * 0 Success
974 * !0 Failure 975 * !0 Failure
975 */ 976 */
976int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) 977int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
978 const struct attribute_group **groups)
977{ 979{
978 int i, err; 980 int i, err;
979 981
@@ -997,6 +999,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
997 999
998 mci->dev.parent = mci_pdev; 1000 mci->dev.parent = mci_pdev;
999 mci->dev.bus = mci->bus; 1001 mci->dev.bus = mci->bus;
1002 mci->dev.groups = groups;
1000 dev_set_name(&mci->dev, "mc%d", mci->mc_idx); 1003 dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
1001 dev_set_drvdata(&mci->dev, mci); 1004 dev_set_drvdata(&mci->dev, mci);
1002 pm_runtime_forbid(&mci->dev); 1005 pm_runtime_forbid(&mci->dev);
@@ -1008,23 +1011,6 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
1008 goto fail_unregister_bus; 1011 goto fail_unregister_bus;
1009 } 1012 }
1010 1013
1011 if (mci->set_sdram_scrub_rate || mci->get_sdram_scrub_rate) {
1012 if (mci->get_sdram_scrub_rate) {
1013 dev_attr_sdram_scrub_rate.attr.mode |= S_IRUGO;
1014 dev_attr_sdram_scrub_rate.show = &mci_sdram_scrub_rate_show;
1015 }
1016
1017 if (mci->set_sdram_scrub_rate) {
1018 dev_attr_sdram_scrub_rate.attr.mode |= S_IWUSR;
1019 dev_attr_sdram_scrub_rate.store = &mci_sdram_scrub_rate_store;
1020 }
1021
1022 err = device_create_file(&mci->dev, &dev_attr_sdram_scrub_rate);
1023 if (err) {
1024 edac_dbg(1, "failure: create sdram_scrub_rate\n");
1025 goto fail_unregister_dev;
1026 }
1027 }
1028 /* 1014 /*
1029 * Create the dimm/rank devices 1015 * Create the dimm/rank devices
1030 */ 1016 */
@@ -1071,7 +1057,6 @@ fail_unregister_dimm:
1071 1057
1072 device_unregister(&dimm->dev); 1058 device_unregister(&dimm->dev);
1073 } 1059 }
1074fail_unregister_dev:
1075 device_unregister(&mci->dev); 1060 device_unregister(&mci->dev);
1076fail_unregister_bus: 1061fail_unregister_bus:
1077 bus_unregister(mci->bus); 1062 bus_unregister(mci->bus);
@@ -1170,7 +1155,7 @@ int __init edac_mc_sysfs_init(void)
1170 return err; 1155 return err;
1171} 1156}
1172 1157
1173void __exit edac_mc_sysfs_exit(void) 1158void edac_mc_sysfs_exit(void)
1174{ 1159{
1175 device_unregister(mci_pdev); 1160 device_unregister(mci_pdev);
1176 edac_put_sysfs_subsys(); 1161 edac_put_sysfs_subsys();
diff --git a/drivers/edac/edac_module.c b/drivers/edac/edac_module.c
index e6d1691dfa45..9cb082a19d8a 100644
--- a/drivers/edac/edac_module.c
+++ b/drivers/edac/edac_module.c
@@ -112,20 +112,23 @@ static int __init edac_init(void)
112 112
113 err = edac_mc_sysfs_init(); 113 err = edac_mc_sysfs_init();
114 if (err) 114 if (err)
115 goto error; 115 goto err_sysfs;
116 116
117 edac_debugfs_init(); 117 edac_debugfs_init();
118 118
119 /* Setup/Initialize the workq for this core */
120 err = edac_workqueue_setup(); 119 err = edac_workqueue_setup();
121 if (err) { 120 if (err) {
122 edac_printk(KERN_ERR, EDAC_MC, "init WorkQueue failure\n"); 121 edac_printk(KERN_ERR, EDAC_MC, "Failure initializing workqueue\n");
123 goto error; 122 goto err_wq;
124 } 123 }
125 124
126 return 0; 125 return 0;
127 126
128error: 127err_wq:
128 edac_debugfs_exit();
129 edac_mc_sysfs_exit();
130
131err_sysfs:
129 return err; 132 return err;
130} 133}
131 134
diff --git a/drivers/edac/edac_module.h b/drivers/edac/edac_module.h
index f2118bfcf8df..26ecc52e073d 100644
--- a/drivers/edac/edac_module.h
+++ b/drivers/edac/edac_module.h
@@ -22,7 +22,8 @@
22 /* on edac_mc_sysfs.c */ 22 /* on edac_mc_sysfs.c */
23int edac_mc_sysfs_init(void); 23int edac_mc_sysfs_init(void);
24void edac_mc_sysfs_exit(void); 24void edac_mc_sysfs_exit(void);
25extern int edac_create_sysfs_mci_device(struct mem_ctl_info *mci); 25extern int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
26 const struct attribute_group **groups);
26extern void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci); 27extern void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci);
27void edac_unregister_sysfs(struct mem_ctl_info *mci); 28void edac_unregister_sysfs(struct mem_ctl_info *mci);
28extern int edac_get_log_ue(void); 29extern int edac_get_log_ue(void);
diff --git a/drivers/edac/highbank_mc_edac.c b/drivers/edac/highbank_mc_edac.c
index f784de1dc793..11260cc3360e 100644
--- a/drivers/edac/highbank_mc_edac.c
+++ b/drivers/edac/highbank_mc_edac.c
@@ -124,6 +124,13 @@ static ssize_t highbank_mc_inject_ctrl(struct device *dev,
124 124
125static DEVICE_ATTR(inject_ctrl, S_IWUSR, NULL, highbank_mc_inject_ctrl); 125static DEVICE_ATTR(inject_ctrl, S_IWUSR, NULL, highbank_mc_inject_ctrl);
126 126
127static struct attribute *highbank_dev_attrs[] = {
128 &dev_attr_inject_ctrl.attr,
129 NULL
130};
131
132ATTRIBUTE_GROUPS(highbank_dev);
133
127struct hb_mc_settings { 134struct hb_mc_settings {
128 int err_offset; 135 int err_offset;
129 int int_offset; 136 int int_offset;
@@ -139,7 +146,7 @@ static struct hb_mc_settings mw_settings = {
139 .int_offset = MW_DDR_ECC_INT_BASE, 146 .int_offset = MW_DDR_ECC_INT_BASE,
140}; 147};
141 148
142static struct of_device_id hb_ddr_ctrl_of_match[] = { 149static const struct of_device_id hb_ddr_ctrl_of_match[] = {
143 { .compatible = "calxeda,hb-ddr-ctrl", .data = &hb_settings }, 150 { .compatible = "calxeda,hb-ddr-ctrl", .data = &hb_settings },
144 { .compatible = "calxeda,ecx-2000-ddr-ctrl", .data = &mw_settings }, 151 { .compatible = "calxeda,ecx-2000-ddr-ctrl", .data = &mw_settings },
145 {}, 152 {},
@@ -231,7 +238,7 @@ static int highbank_mc_probe(struct platform_device *pdev)
231 dimm->mtype = MEM_DDR3; 238 dimm->mtype = MEM_DDR3;
232 dimm->edac_mode = EDAC_SECDED; 239 dimm->edac_mode = EDAC_SECDED;
233 240
234 res = edac_mc_add_mc(mci); 241 res = edac_mc_add_mc_with_groups(mci, highbank_dev_groups);
235 if (res < 0) 242 if (res < 0)
236 goto err; 243 goto err;
237 244
@@ -243,8 +250,6 @@ static int highbank_mc_probe(struct platform_device *pdev)
243 goto err2; 250 goto err2;
244 } 251 }
245 252
246 device_create_file(&mci->dev, &dev_attr_inject_ctrl);
247
248 devres_close_group(&pdev->dev, NULL); 253 devres_close_group(&pdev->dev, NULL);
249 return 0; 254 return 0;
250err2: 255err2:
@@ -259,7 +264,6 @@ static int highbank_mc_remove(struct platform_device *pdev)
259{ 264{
260 struct mem_ctl_info *mci = platform_get_drvdata(pdev); 265 struct mem_ctl_info *mci = platform_get_drvdata(pdev);
261 266
262 device_remove_file(&mci->dev, &dev_attr_inject_ctrl);
263 edac_mc_del_mc(&pdev->dev); 267 edac_mc_del_mc(&pdev->dev);
264 edac_mc_free(mci); 268 edac_mc_free(mci);
265 return 0; 269 return 0;
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 9cd0b301f81b..01087a38da22 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1157,27 +1157,24 @@ static DEVICE_ATTR(inject_eccmask, S_IRUGO | S_IWUSR,
1157static DEVICE_ATTR(inject_enable, S_IRUGO | S_IWUSR, 1157static DEVICE_ATTR(inject_enable, S_IRUGO | S_IWUSR,
1158 i7core_inject_enable_show, i7core_inject_enable_store); 1158 i7core_inject_enable_show, i7core_inject_enable_store);
1159 1159
1160static struct attribute *i7core_dev_attrs[] = {
1161 &dev_attr_inject_section.attr,
1162 &dev_attr_inject_type.attr,
1163 &dev_attr_inject_eccmask.attr,
1164 &dev_attr_inject_enable.attr,
1165 NULL
1166};
1167
1168ATTRIBUTE_GROUPS(i7core_dev);
1169
1160static int i7core_create_sysfs_devices(struct mem_ctl_info *mci) 1170static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
1161{ 1171{
1162 struct i7core_pvt *pvt = mci->pvt_info; 1172 struct i7core_pvt *pvt = mci->pvt_info;
1163 int rc; 1173 int rc;
1164 1174
1165 rc = device_create_file(&mci->dev, &dev_attr_inject_section);
1166 if (rc < 0)
1167 return rc;
1168 rc = device_create_file(&mci->dev, &dev_attr_inject_type);
1169 if (rc < 0)
1170 return rc;
1171 rc = device_create_file(&mci->dev, &dev_attr_inject_eccmask);
1172 if (rc < 0)
1173 return rc;
1174 rc = device_create_file(&mci->dev, &dev_attr_inject_enable);
1175 if (rc < 0)
1176 return rc;
1177
1178 pvt->addrmatch_dev = kzalloc(sizeof(*pvt->addrmatch_dev), GFP_KERNEL); 1175 pvt->addrmatch_dev = kzalloc(sizeof(*pvt->addrmatch_dev), GFP_KERNEL);
1179 if (!pvt->addrmatch_dev) 1176 if (!pvt->addrmatch_dev)
1180 return rc; 1177 return -ENOMEM;
1181 1178
1182 pvt->addrmatch_dev->type = &addrmatch_type; 1179 pvt->addrmatch_dev->type = &addrmatch_type;
1183 pvt->addrmatch_dev->bus = mci->dev.bus; 1180 pvt->addrmatch_dev->bus = mci->dev.bus;
@@ -1198,7 +1195,7 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
1198 if (!pvt->chancounts_dev) { 1195 if (!pvt->chancounts_dev) {
1199 put_device(pvt->addrmatch_dev); 1196 put_device(pvt->addrmatch_dev);
1200 device_del(pvt->addrmatch_dev); 1197 device_del(pvt->addrmatch_dev);
1201 return rc; 1198 return -ENOMEM;
1202 } 1199 }
1203 1200
1204 pvt->chancounts_dev->type = &all_channel_counts_type; 1201 pvt->chancounts_dev->type = &all_channel_counts_type;
@@ -1223,11 +1220,6 @@ static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
1223 1220
1224 edac_dbg(1, "\n"); 1221 edac_dbg(1, "\n");
1225 1222
1226 device_remove_file(&mci->dev, &dev_attr_inject_section);
1227 device_remove_file(&mci->dev, &dev_attr_inject_type);
1228 device_remove_file(&mci->dev, &dev_attr_inject_eccmask);
1229 device_remove_file(&mci->dev, &dev_attr_inject_enable);
1230
1231 if (!pvt->is_registered) { 1223 if (!pvt->is_registered) {
1232 put_device(pvt->chancounts_dev); 1224 put_device(pvt->chancounts_dev);
1233 device_del(pvt->chancounts_dev); 1225 device_del(pvt->chancounts_dev);
@@ -2259,7 +2251,7 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev)
2259 enable_sdram_scrub_setting(mci); 2251 enable_sdram_scrub_setting(mci);
2260 2252
2261 /* add this new MC control structure to EDAC's list of MCs */ 2253 /* add this new MC control structure to EDAC's list of MCs */
2262 if (unlikely(edac_mc_add_mc(mci))) { 2254 if (unlikely(edac_mc_add_mc_with_groups(mci, i7core_dev_groups))) {
2263 edac_dbg(0, "MC: failed edac_mc_add_mc()\n"); 2255 edac_dbg(0, "MC: failed edac_mc_add_mc()\n");
2264 /* FIXME: perhaps some code should go here that disables error 2256 /* FIXME: perhaps some code should go here that disables error
2265 * reporting if we just enabled it 2257 * reporting if we just enabled it
diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c
index b4705d9366bf..4d4110364f02 100644
--- a/drivers/edac/i82443bxgx_edac.c
+++ b/drivers/edac/i82443bxgx_edac.c
@@ -350,8 +350,6 @@ fail:
350 return -ENODEV; 350 return -ENODEV;
351} 351}
352 352
353EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_probe1);
354
355/* returns count (>= 0), or negative on error */ 353/* returns count (>= 0), or negative on error */
356static int i82443bxgx_edacmc_init_one(struct pci_dev *pdev, 354static int i82443bxgx_edacmc_init_one(struct pci_dev *pdev,
357 const struct pci_device_id *ent) 355 const struct pci_device_id *ent)
@@ -384,8 +382,6 @@ static void i82443bxgx_edacmc_remove_one(struct pci_dev *pdev)
384 edac_mc_free(mci); 382 edac_mc_free(mci);
385} 383}
386 384
387EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_remove_one);
388
389static const struct pci_device_id i82443bxgx_pci_tbl[] = { 385static const struct pci_device_id i82443bxgx_pci_tbl[] = {
390 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0)}, 386 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0)},
391 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2)}, 387 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2)},
@@ -445,9 +441,7 @@ fail1:
445 pci_unregister_driver(&i82443bxgx_edacmc_driver); 441 pci_unregister_driver(&i82443bxgx_edacmc_driver);
446 442
447fail0: 443fail0:
448 if (mci_pdev != NULL) 444 pci_dev_put(mci_pdev);
449 pci_dev_put(mci_pdev);
450
451 return pci_rc; 445 return pci_rc;
452} 446}
453 447
diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c
index 4382343a7c60..ee1078cd3b96 100644
--- a/drivers/edac/i82860_edac.c
+++ b/drivers/edac/i82860_edac.c
@@ -343,20 +343,15 @@ fail1:
343 pci_unregister_driver(&i82860_driver); 343 pci_unregister_driver(&i82860_driver);
344 344
345fail0: 345fail0:
346 if (mci_pdev != NULL) 346 pci_dev_put(mci_pdev);
347 pci_dev_put(mci_pdev);
348
349 return pci_rc; 347 return pci_rc;
350} 348}
351 349
352static void __exit i82860_exit(void) 350static void __exit i82860_exit(void)
353{ 351{
354 edac_dbg(3, "\n"); 352 edac_dbg(3, "\n");
355
356 pci_unregister_driver(&i82860_driver); 353 pci_unregister_driver(&i82860_driver);
357 354 pci_dev_put(mci_pdev);
358 if (mci_pdev != NULL)
359 pci_dev_put(mci_pdev);
360} 355}
361 356
362module_init(i82860_init); 357module_init(i82860_init);
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c
index 64b68320249f..c26a513f8869 100644
--- a/drivers/edac/i82875p_edac.c
+++ b/drivers/edac/i82875p_edac.c
@@ -576,9 +576,7 @@ fail1:
576 pci_unregister_driver(&i82875p_driver); 576 pci_unregister_driver(&i82875p_driver);
577 577
578fail0: 578fail0:
579 if (mci_pdev != NULL) 579 pci_dev_put(mci_pdev);
580 pci_dev_put(mci_pdev);
581
582 return pci_rc; 580 return pci_rc;
583} 581}
584 582
diff --git a/drivers/edac/i82975x_edac.c b/drivers/edac/i82975x_edac.c
index 10b10521f62e..35ab66c623a3 100644
--- a/drivers/edac/i82975x_edac.c
+++ b/drivers/edac/i82975x_edac.c
@@ -685,9 +685,7 @@ fail1:
685 pci_unregister_driver(&i82975x_driver); 685 pci_unregister_driver(&i82975x_driver);
686 686
687fail0: 687fail0:
688 if (mci_pdev != NULL) 688 pci_dev_put(mci_pdev);
689 pci_dev_put(mci_pdev);
690
691 return pci_rc; 689 return pci_rc;
692} 690}
693 691
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 1fa76a588af3..68bf234bdfe6 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -134,29 +134,14 @@ DEVICE_ATTR(inject_data_lo, S_IRUGO | S_IWUSR,
134DEVICE_ATTR(inject_ctrl, S_IRUGO | S_IWUSR, 134DEVICE_ATTR(inject_ctrl, S_IRUGO | S_IWUSR,
135 mpc85xx_mc_inject_ctrl_show, mpc85xx_mc_inject_ctrl_store); 135 mpc85xx_mc_inject_ctrl_show, mpc85xx_mc_inject_ctrl_store);
136 136
137static int mpc85xx_create_sysfs_attributes(struct mem_ctl_info *mci) 137static struct attribute *mpc85xx_dev_attrs[] = {
138{ 138 &dev_attr_inject_data_hi.attr,
139 int rc; 139 &dev_attr_inject_data_lo.attr,
140 140 &dev_attr_inject_ctrl.attr,
141 rc = device_create_file(&mci->dev, &dev_attr_inject_data_hi); 141 NULL
142 if (rc < 0) 142};
143 return rc;
144 rc = device_create_file(&mci->dev, &dev_attr_inject_data_lo);
145 if (rc < 0)
146 return rc;
147 rc = device_create_file(&mci->dev, &dev_attr_inject_ctrl);
148 if (rc < 0)
149 return rc;
150 143
151 return 0; 144ATTRIBUTE_GROUPS(mpc85xx_dev);
152}
153
154static void mpc85xx_remove_sysfs_attributes(struct mem_ctl_info *mci)
155{
156 device_remove_file(&mci->dev, &dev_attr_inject_data_hi);
157 device_remove_file(&mci->dev, &dev_attr_inject_data_lo);
158 device_remove_file(&mci->dev, &dev_attr_inject_ctrl);
159}
160 145
161/**************************** PCI Err device ***************************/ 146/**************************** PCI Err device ***************************/
162#ifdef CONFIG_PCI 147#ifdef CONFIG_PCI
@@ -685,7 +670,7 @@ static int mpc85xx_l2_err_remove(struct platform_device *op)
685 return 0; 670 return 0;
686} 671}
687 672
688static struct of_device_id mpc85xx_l2_err_of_match[] = { 673static const struct of_device_id mpc85xx_l2_err_of_match[] = {
689/* deprecate the fsl,85.. forms in the future, 2.6.30? */ 674/* deprecate the fsl,85.. forms in the future, 2.6.30? */
690 { .compatible = "fsl,8540-l2-cache-controller", }, 675 { .compatible = "fsl,8540-l2-cache-controller", },
691 { .compatible = "fsl,8541-l2-cache-controller", }, 676 { .compatible = "fsl,8541-l2-cache-controller", },
@@ -1106,13 +1091,7 @@ static int mpc85xx_mc_err_probe(struct platform_device *op)
1106 /* clear all error bits */ 1091 /* clear all error bits */
1107 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0); 1092 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0);
1108 1093
1109 if (edac_mc_add_mc(mci)) { 1094 if (edac_mc_add_mc_with_groups(mci, mpc85xx_dev_groups)) {
1110 edac_dbg(3, "failed edac_mc_add_mc()\n");
1111 goto err;
1112 }
1113
1114 if (mpc85xx_create_sysfs_attributes(mci)) {
1115 edac_mc_del_mc(mci->pdev);
1116 edac_dbg(3, "failed edac_mc_add_mc()\n"); 1095 edac_dbg(3, "failed edac_mc_add_mc()\n");
1117 goto err; 1096 goto err;
1118 } 1097 }
@@ -1176,13 +1155,12 @@ static int mpc85xx_mc_err_remove(struct platform_device *op)
1176 orig_ddr_err_disable); 1155 orig_ddr_err_disable);
1177 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, orig_ddr_err_sbe); 1156 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, orig_ddr_err_sbe);
1178 1157
1179 mpc85xx_remove_sysfs_attributes(mci);
1180 edac_mc_del_mc(&op->dev); 1158 edac_mc_del_mc(&op->dev);
1181 edac_mc_free(mci); 1159 edac_mc_free(mci);
1182 return 0; 1160 return 0;
1183} 1161}
1184 1162
1185static struct of_device_id mpc85xx_mc_err_of_match[] = { 1163static const struct of_device_id mpc85xx_mc_err_of_match[] = {
1186/* deprecate the fsl,85.. forms in the future, 2.6.30? */ 1164/* deprecate the fsl,85.. forms in the future, 2.6.30? */
1187 { .compatible = "fsl,8540-memory-controller", }, 1165 { .compatible = "fsl,8540-memory-controller", },
1188 { .compatible = "fsl,8541-memory-controller", }, 1166 { .compatible = "fsl,8541-memory-controller", },
diff --git a/drivers/edac/octeon_edac-lmc.c b/drivers/edac/octeon_edac-lmc.c
index 4bd10f94f068..bb19e0732681 100644
--- a/drivers/edac/octeon_edac-lmc.c
+++ b/drivers/edac/octeon_edac-lmc.c
@@ -209,35 +209,18 @@ static DEVICE_ATTR(row, S_IRUGO | S_IWUSR,
209static DEVICE_ATTR(col, S_IRUGO | S_IWUSR, 209static DEVICE_ATTR(col, S_IRUGO | S_IWUSR,
210 octeon_mc_inject_col_show, octeon_mc_inject_col_store); 210 octeon_mc_inject_col_show, octeon_mc_inject_col_store);
211 211
212static struct attribute *octeon_dev_attrs[] = {
213 &dev_attr_inject.attr,
214 &dev_attr_error_type.attr,
215 &dev_attr_dimm.attr,
216 &dev_attr_rank.attr,
217 &dev_attr_bank.attr,
218 &dev_attr_row.attr,
219 &dev_attr_col.attr,
220 NULL
221};
212 222
213static int octeon_set_mc_sysfs_attributes(struct mem_ctl_info *mci) 223ATTRIBUTE_GROUPS(octeon_dev);
214{
215 int rc;
216
217 rc = device_create_file(&mci->dev, &dev_attr_inject);
218 if (rc < 0)
219 return rc;
220 rc = device_create_file(&mci->dev, &dev_attr_error_type);
221 if (rc < 0)
222 return rc;
223 rc = device_create_file(&mci->dev, &dev_attr_dimm);
224 if (rc < 0)
225 return rc;
226 rc = device_create_file(&mci->dev, &dev_attr_rank);
227 if (rc < 0)
228 return rc;
229 rc = device_create_file(&mci->dev, &dev_attr_bank);
230 if (rc < 0)
231 return rc;
232 rc = device_create_file(&mci->dev, &dev_attr_row);
233 if (rc < 0)
234 return rc;
235 rc = device_create_file(&mci->dev, &dev_attr_col);
236 if (rc < 0)
237 return rc;
238
239 return 0;
240}
241 224
242static int octeon_lmc_edac_probe(struct platform_device *pdev) 225static int octeon_lmc_edac_probe(struct platform_device *pdev)
243{ 226{
@@ -271,18 +254,12 @@ static int octeon_lmc_edac_probe(struct platform_device *pdev)
271 mci->ctl_name = "octeon-lmc-err"; 254 mci->ctl_name = "octeon-lmc-err";
272 mci->edac_check = octeon_lmc_edac_poll; 255 mci->edac_check = octeon_lmc_edac_poll;
273 256
274 if (edac_mc_add_mc(mci)) { 257 if (edac_mc_add_mc_with_groups(mci, octeon_dev_groups)) {
275 dev_err(&pdev->dev, "edac_mc_add_mc() failed\n"); 258 dev_err(&pdev->dev, "edac_mc_add_mc() failed\n");
276 edac_mc_free(mci); 259 edac_mc_free(mci);
277 return -ENXIO; 260 return -ENXIO;
278 } 261 }
279 262
280 if (octeon_set_mc_sysfs_attributes(mci)) {
281 dev_err(&pdev->dev, "octeon_set_mc_sysfs_attributes() failed\n");
282 return -ENXIO;
283 }
284
285
286 cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc)); 263 cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc));
287 cfg0.s.intr_ded_ena = 0; /* We poll */ 264 cfg0.s.intr_ded_ena = 0; /* We poll */
288 cfg0.s.intr_sec_ena = 0; 265 cfg0.s.intr_sec_ena = 0;
@@ -309,18 +286,12 @@ static int octeon_lmc_edac_probe(struct platform_device *pdev)
309 mci->ctl_name = "co_lmc_err"; 286 mci->ctl_name = "co_lmc_err";
310 mci->edac_check = octeon_lmc_edac_poll_o2; 287 mci->edac_check = octeon_lmc_edac_poll_o2;
311 288
312 if (edac_mc_add_mc(mci)) { 289 if (edac_mc_add_mc_with_groups(mci, octeon_dev_groups)) {
313 dev_err(&pdev->dev, "edac_mc_add_mc() failed\n"); 290 dev_err(&pdev->dev, "edac_mc_add_mc() failed\n");
314 edac_mc_free(mci); 291 edac_mc_free(mci);
315 return -ENXIO; 292 return -ENXIO;
316 } 293 }
317 294
318 if (octeon_set_mc_sysfs_attributes(mci)) {
319 dev_err(&pdev->dev, "octeon_set_mc_sysfs_attributes() failed\n");
320 return -ENXIO;
321 }
322
323
324 en.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc)); 295 en.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc));
325 en.s.intr_ded_ena = 0; /* We poll */ 296 en.s.intr_ded_ena = 0; /* We poll */
326 en.s.intr_sec_ena = 0; 297 en.s.intr_sec_ena = 0;
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c
index 1b64fd060821..3515b381c131 100644
--- a/drivers/edac/ppc4xx_edac.c
+++ b/drivers/edac/ppc4xx_edac.c
@@ -193,7 +193,7 @@ static int ppc4xx_edac_remove(struct platform_device *device);
193 * Device tree node type and compatible tuples this driver can match 193 * Device tree node type and compatible tuples this driver can match
194 * on. 194 * on.
195 */ 195 */
196static struct of_device_id ppc4xx_edac_match[] = { 196static const struct of_device_id ppc4xx_edac_match[] = {
197 { 197 {
198 .compatible = "ibm,sdram-4xx-ddr2" 198 .compatible = "ibm,sdram-4xx-ddr2"
199 }, 199 },
diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 1c9691535e13..fc153aea2f6c 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -512,7 +512,7 @@ static int synps_edac_mc_remove(struct platform_device *pdev)
512 return 0; 512 return 0;
513} 513}
514 514
515static struct of_device_id synps_edac_match[] = { 515static const struct of_device_id synps_edac_match[] = {
516 { .compatible = "xlnx,zynq-ddrc-a05", }, 516 { .compatible = "xlnx,zynq-ddrc-a05", },
517 { /* end of table */ } 517 { /* end of table */ }
518}; 518};