aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-03-21 10:08:06 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-06-11 12:23:41 -0400
commit5c4cdb5ae72988ef93f72ad6f46be0e4eea5be8d (patch)
tree209b4462654701012593482c7b10bdccdf6ef08b
parentc56087595fb6531f359925b581529f1b2aef10f1 (diff)
i7core_edac: convert it to use struct device
Instead of relying on a complex logic inside the edac core to create a "device tree-like" sysfs struct, just use device_add. Reviewed-by: Aristeu Rozanski <arozansk@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/edac/i7core_edac.c338
1 files changed, 209 insertions, 129 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 598d215f7bd..ab3b84b906b 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -248,6 +248,8 @@ struct i7core_dev {
248}; 248};
249 249
250struct i7core_pvt { 250struct i7core_pvt {
251 struct device addrmatch_dev, chancounts_dev;
252
251 struct pci_dev *pci_noncore; 253 struct pci_dev *pci_noncore;
252 struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1]; 254 struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1];
253 struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1]; 255 struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1];
@@ -662,6 +664,8 @@ static int get_dimm_config(struct mem_ctl_info *mci)
662 Error insertion routines 664 Error insertion routines
663 ****************************************************************************/ 665 ****************************************************************************/
664 666
667#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
668
665/* The i7core has independent error injection features per channel. 669/* The i7core has independent error injection features per channel.
666 However, to have a simpler code, we don't allow enabling error injection 670 However, to have a simpler code, we don't allow enabling error injection
667 on more than one channel. 671 on more than one channel.
@@ -691,9 +695,11 @@ static int disable_inject(const struct mem_ctl_info *mci)
691 * bit 0 - refers to the lower 32-byte half cacheline 695 * bit 0 - refers to the lower 32-byte half cacheline
692 * bit 1 - refers to the upper 32-byte half cacheline 696 * bit 1 - refers to the upper 32-byte half cacheline
693 */ 697 */
694static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci, 698static ssize_t i7core_inject_section_store(struct device *dev,
699 struct device_attribute *mattr,
695 const char *data, size_t count) 700 const char *data, size_t count)
696{ 701{
702 struct mem_ctl_info *mci = to_mci(dev);
697 struct i7core_pvt *pvt = mci->pvt_info; 703 struct i7core_pvt *pvt = mci->pvt_info;
698 unsigned long value; 704 unsigned long value;
699 int rc; 705 int rc;
@@ -709,9 +715,11 @@ static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci,
709 return count; 715 return count;
710} 716}
711 717
712static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci, 718static ssize_t i7core_inject_section_show(struct device *dev,
713 char *data) 719 struct device_attribute *mattr,
720 char *data)
714{ 721{
722 struct mem_ctl_info *mci = to_mci(dev);
715 struct i7core_pvt *pvt = mci->pvt_info; 723 struct i7core_pvt *pvt = mci->pvt_info;
716 return sprintf(data, "0x%08x\n", pvt->inject.section); 724 return sprintf(data, "0x%08x\n", pvt->inject.section);
717} 725}
@@ -724,10 +732,12 @@ static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci,
724 * bit 1 - inject ECC error 732 * bit 1 - inject ECC error
725 * bit 2 - inject parity error 733 * bit 2 - inject parity error
726 */ 734 */
727static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci, 735static ssize_t i7core_inject_type_store(struct device *dev,
736 struct device_attribute *mattr,
728 const char *data, size_t count) 737 const char *data, size_t count)
729{ 738{
730 struct i7core_pvt *pvt = mci->pvt_info; 739 struct mem_ctl_info *mci = to_mci(dev);
740struct i7core_pvt *pvt = mci->pvt_info;
731 unsigned long value; 741 unsigned long value;
732 int rc; 742 int rc;
733 743
@@ -742,10 +752,13 @@ static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci,
742 return count; 752 return count;
743} 753}
744 754
745static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci, 755static ssize_t i7core_inject_type_show(struct device *dev,
746 char *data) 756 struct device_attribute *mattr,
757 char *data)
747{ 758{
759 struct mem_ctl_info *mci = to_mci(dev);
748 struct i7core_pvt *pvt = mci->pvt_info; 760 struct i7core_pvt *pvt = mci->pvt_info;
761
749 return sprintf(data, "0x%08x\n", pvt->inject.type); 762 return sprintf(data, "0x%08x\n", pvt->inject.type);
750} 763}
751 764
@@ -759,9 +772,11 @@ static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci,
759 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an 772 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
760 * uncorrectable error to be injected. 773 * uncorrectable error to be injected.
761 */ 774 */
762static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci, 775static ssize_t i7core_inject_eccmask_store(struct device *dev,
763 const char *data, size_t count) 776 struct device_attribute *mattr,
777 const char *data, size_t count)
764{ 778{
779 struct mem_ctl_info *mci = to_mci(dev);
765 struct i7core_pvt *pvt = mci->pvt_info; 780 struct i7core_pvt *pvt = mci->pvt_info;
766 unsigned long value; 781 unsigned long value;
767 int rc; 782 int rc;
@@ -777,10 +792,13 @@ static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci,
777 return count; 792 return count;
778} 793}
779 794
780static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci, 795static ssize_t i7core_inject_eccmask_show(struct device *dev,
781 char *data) 796 struct device_attribute *mattr,
797 char *data)
782{ 798{
799 struct mem_ctl_info *mci = to_mci(dev);
783 struct i7core_pvt *pvt = mci->pvt_info; 800 struct i7core_pvt *pvt = mci->pvt_info;
801
784 return sprintf(data, "0x%08x\n", pvt->inject.eccmask); 802 return sprintf(data, "0x%08x\n", pvt->inject.eccmask);
785} 803}
786 804
@@ -797,9 +815,11 @@ static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci,
797 815
798#define DECLARE_ADDR_MATCH(param, limit) \ 816#define DECLARE_ADDR_MATCH(param, limit) \
799static ssize_t i7core_inject_store_##param( \ 817static ssize_t i7core_inject_store_##param( \
800 struct mem_ctl_info *mci, \ 818 struct device *dev, \
801 const char *data, size_t count) \ 819 struct device_attribute *mattr, \
820 const char *data, size_t count) \
802{ \ 821{ \
822 struct mem_ctl_info *mci = to_mci(dev); \
803 struct i7core_pvt *pvt; \ 823 struct i7core_pvt *pvt; \
804 long value; \ 824 long value; \
805 int rc; \ 825 int rc; \
@@ -824,9 +844,11 @@ static ssize_t i7core_inject_store_##param( \
824} \ 844} \
825 \ 845 \
826static ssize_t i7core_inject_show_##param( \ 846static ssize_t i7core_inject_show_##param( \
827 struct mem_ctl_info *mci, \ 847 struct device *dev, \
828 char *data) \ 848 struct device_attribute *mattr, \
849 char *data) \
829{ \ 850{ \
851 struct mem_ctl_info *mci = to_mci(dev); \
830 struct i7core_pvt *pvt; \ 852 struct i7core_pvt *pvt; \
831 \ 853 \
832 pvt = mci->pvt_info; \ 854 pvt = mci->pvt_info; \
@@ -838,14 +860,9 @@ static ssize_t i7core_inject_show_##param( \
838} 860}
839 861
840#define ATTR_ADDR_MATCH(param) \ 862#define ATTR_ADDR_MATCH(param) \
841 { \ 863 static DEVICE_ATTR(param, S_IRUGO | S_IWUSR, \
842 .attr = { \ 864 i7core_inject_show_##param, \
843 .name = #param, \ 865 i7core_inject_store_##param)
844 .mode = (S_IRUGO | S_IWUSR) \
845 }, \
846 .show = i7core_inject_show_##param, \
847 .store = i7core_inject_store_##param, \
848 }
849 866
850DECLARE_ADDR_MATCH(channel, 3); 867DECLARE_ADDR_MATCH(channel, 3);
851DECLARE_ADDR_MATCH(dimm, 3); 868DECLARE_ADDR_MATCH(dimm, 3);
@@ -854,6 +871,13 @@ DECLARE_ADDR_MATCH(bank, 32);
854DECLARE_ADDR_MATCH(page, 0x10000); 871DECLARE_ADDR_MATCH(page, 0x10000);
855DECLARE_ADDR_MATCH(col, 0x4000); 872DECLARE_ADDR_MATCH(col, 0x4000);
856 873
874ATTR_ADDR_MATCH(channel);
875ATTR_ADDR_MATCH(dimm);
876ATTR_ADDR_MATCH(rank);
877ATTR_ADDR_MATCH(bank);
878ATTR_ADDR_MATCH(page);
879ATTR_ADDR_MATCH(col);
880
857static int write_and_test(struct pci_dev *dev, const int where, const u32 val) 881static int write_and_test(struct pci_dev *dev, const int where, const u32 val)
858{ 882{
859 u32 read; 883 u32 read;
@@ -899,9 +923,11 @@ static int write_and_test(struct pci_dev *dev, const int where, const u32 val)
899 * is reliable enough to check if the MC is using the 923 * is reliable enough to check if the MC is using the
900 * three channels. However, this is not clear at the datasheet. 924 * three channels. However, this is not clear at the datasheet.
901 */ 925 */
902static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, 926static ssize_t i7core_inject_enable_store(struct device *dev,
903 const char *data, size_t count) 927 struct device_attribute *mattr,
928 const char *data, size_t count)
904{ 929{
930 struct mem_ctl_info *mci = to_mci(dev);
905 struct i7core_pvt *pvt = mci->pvt_info; 931 struct i7core_pvt *pvt = mci->pvt_info;
906 u32 injectmask; 932 u32 injectmask;
907 u64 mask = 0; 933 u64 mask = 0;
@@ -1002,9 +1028,11 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
1002 return count; 1028 return count;
1003} 1029}
1004 1030
1005static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, 1031static ssize_t i7core_inject_enable_show(struct device *dev,
1006 char *data) 1032 struct device_attribute *mattr,
1033 char *data)
1007{ 1034{
1035 struct mem_ctl_info *mci = to_mci(dev);
1008 struct i7core_pvt *pvt = mci->pvt_info; 1036 struct i7core_pvt *pvt = mci->pvt_info;
1009 u32 injectmask; 1037 u32 injectmask;
1010 1038
@@ -1024,12 +1052,14 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci,
1024 1052
1025#define DECLARE_COUNTER(param) \ 1053#define DECLARE_COUNTER(param) \
1026static ssize_t i7core_show_counter_##param( \ 1054static ssize_t i7core_show_counter_##param( \
1027 struct mem_ctl_info *mci, \ 1055 struct device *dev, \
1028 char *data) \ 1056 struct device_attribute *mattr, \
1057 char *data) \
1029{ \ 1058{ \
1059 struct mem_ctl_info *mci = to_mci(dev); \
1030 struct i7core_pvt *pvt = mci->pvt_info; \ 1060 struct i7core_pvt *pvt = mci->pvt_info; \
1031 \ 1061 \
1032 debugf1("%s() \n", __func__); \ 1062 debugf1("%s()\n", __func__); \
1033 if (!pvt->ce_count_available || (pvt->is_registered)) \ 1063 if (!pvt->ce_count_available || (pvt->is_registered)) \
1034 return sprintf(data, "data unavailable\n"); \ 1064 return sprintf(data, "data unavailable\n"); \
1035 return sprintf(data, "%lu\n", \ 1065 return sprintf(data, "%lu\n", \
@@ -1037,121 +1067,167 @@ static ssize_t i7core_show_counter_##param( \
1037} 1067}
1038 1068
1039#define ATTR_COUNTER(param) \ 1069#define ATTR_COUNTER(param) \
1040 { \ 1070 static DEVICE_ATTR(udimm##param, S_IRUGO | S_IWUSR, \
1041 .attr = { \ 1071 i7core_show_counter_##param, \
1042 .name = __stringify(udimm##param), \ 1072 NULL)
1043 .mode = (S_IRUGO | S_IWUSR) \
1044 }, \
1045 .show = i7core_show_counter_##param \
1046 }
1047 1073
1048DECLARE_COUNTER(0); 1074DECLARE_COUNTER(0);
1049DECLARE_COUNTER(1); 1075DECLARE_COUNTER(1);
1050DECLARE_COUNTER(2); 1076DECLARE_COUNTER(2);
1051 1077
1078ATTR_COUNTER(0);
1079ATTR_COUNTER(1);
1080ATTR_COUNTER(2);
1081
1052/* 1082/*
1053 * Sysfs struct 1083 * inject_addrmatch device sysfs struct
1054 */ 1084 */
1055 1085
1056static const struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = { 1086static struct attribute *i7core_addrmatch_attrs[] = {
1057 ATTR_ADDR_MATCH(channel), 1087 &dev_attr_channel.attr,
1058 ATTR_ADDR_MATCH(dimm), 1088 &dev_attr_dimm.attr,
1059 ATTR_ADDR_MATCH(rank), 1089 &dev_attr_rank.attr,
1060 ATTR_ADDR_MATCH(bank), 1090 &dev_attr_bank.attr,
1061 ATTR_ADDR_MATCH(page), 1091 &dev_attr_page.attr,
1062 ATTR_ADDR_MATCH(col), 1092 &dev_attr_col.attr,
1063 { } /* End of list */ 1093 NULL
1064}; 1094};
1065 1095
1066static const struct mcidev_sysfs_group i7core_inject_addrmatch = { 1096static struct attribute_group addrmatch_grp = {
1067 .name = "inject_addrmatch", 1097 .attrs = i7core_addrmatch_attrs,
1068 .mcidev_attr = i7core_addrmatch_attrs,
1069}; 1098};
1070 1099
1071static const struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = { 1100static const struct attribute_group *addrmatch_groups[] = {
1072 ATTR_COUNTER(0), 1101 &addrmatch_grp,
1073 ATTR_COUNTER(1), 1102 NULL
1074 ATTR_COUNTER(2),
1075 { .attr = { .name = NULL } }
1076}; 1103};
1077 1104
1078static const struct mcidev_sysfs_group i7core_udimm_counters = { 1105static void addrmatch_release(struct device *device)
1079 .name = "all_channel_counts", 1106{
1080 .mcidev_attr = i7core_udimm_counters_attrs, 1107 debugf1("Releasing device %s\n", dev_name(device));
1108}
1109
1110static struct device_type addrmatch_type = {
1111 .groups = addrmatch_groups,
1112 .release = addrmatch_release,
1081}; 1113};
1082 1114
1083static const struct mcidev_sysfs_attribute i7core_sysfs_rdimm_attrs[] = { 1115/*
1084 { 1116 * all_channel_counts sysfs struct
1085 .attr = { 1117 */
1086 .name = "inject_section", 1118
1087 .mode = (S_IRUGO | S_IWUSR) 1119static struct attribute *i7core_udimm_counters_attrs[] = {
1088 }, 1120 &dev_attr_udimm0.attr,
1089 .show = i7core_inject_section_show, 1121 &dev_attr_udimm1.attr,
1090 .store = i7core_inject_section_store, 1122 &dev_attr_udimm2.attr,
1091 }, { 1123 NULL
1092 .attr = { 1124};
1093 .name = "inject_type", 1125
1094 .mode = (S_IRUGO | S_IWUSR) 1126static struct attribute_group all_channel_counts_grp = {
1095 }, 1127 .attrs = i7core_udimm_counters_attrs,
1096 .show = i7core_inject_type_show,
1097 .store = i7core_inject_type_store,
1098 }, {
1099 .attr = {
1100 .name = "inject_eccmask",
1101 .mode = (S_IRUGO | S_IWUSR)
1102 },
1103 .show = i7core_inject_eccmask_show,
1104 .store = i7core_inject_eccmask_store,
1105 }, {
1106 .grp = &i7core_inject_addrmatch,
1107 }, {
1108 .attr = {
1109 .name = "inject_enable",
1110 .mode = (S_IRUGO | S_IWUSR)
1111 },
1112 .show = i7core_inject_enable_show,
1113 .store = i7core_inject_enable_store,
1114 },
1115 { } /* End of list */
1116}; 1128};
1117 1129
1118static const struct mcidev_sysfs_attribute i7core_sysfs_udimm_attrs[] = { 1130static const struct attribute_group *all_channel_counts_groups[] = {
1119 { 1131 &all_channel_counts_grp,
1120 .attr = { 1132 NULL
1121 .name = "inject_section",
1122 .mode = (S_IRUGO | S_IWUSR)
1123 },
1124 .show = i7core_inject_section_show,
1125 .store = i7core_inject_section_store,
1126 }, {
1127 .attr = {
1128 .name = "inject_type",
1129 .mode = (S_IRUGO | S_IWUSR)
1130 },
1131 .show = i7core_inject_type_show,
1132 .store = i7core_inject_type_store,
1133 }, {
1134 .attr = {
1135 .name = "inject_eccmask",
1136 .mode = (S_IRUGO | S_IWUSR)
1137 },
1138 .show = i7core_inject_eccmask_show,
1139 .store = i7core_inject_eccmask_store,
1140 }, {
1141 .grp = &i7core_inject_addrmatch,
1142 }, {
1143 .attr = {
1144 .name = "inject_enable",
1145 .mode = (S_IRUGO | S_IWUSR)
1146 },
1147 .show = i7core_inject_enable_show,
1148 .store = i7core_inject_enable_store,
1149 }, {
1150 .grp = &i7core_udimm_counters,
1151 },
1152 { } /* End of list */
1153}; 1133};
1154 1134
1135static void all_channel_counts_release(struct device *device)
1136{
1137 debugf1("Releasing device %s\n", dev_name(device));
1138}
1139
1140static struct device_type all_channel_counts_type = {
1141 .groups = all_channel_counts_groups,
1142 .release = all_channel_counts_release,
1143};
1144
1145/*
1146 * inject sysfs attributes
1147 */
1148
1149static DEVICE_ATTR(inject_section, S_IRUGO | S_IWUSR,
1150 i7core_inject_section_show, i7core_inject_section_store);
1151
1152static DEVICE_ATTR(inject_type, S_IRUGO | S_IWUSR,
1153 i7core_inject_type_show, i7core_inject_type_store);
1154
1155
1156static DEVICE_ATTR(inject_eccmask, S_IRUGO | S_IWUSR,
1157 i7core_inject_eccmask_show, i7core_inject_eccmask_store);
1158
1159static DEVICE_ATTR(inject_enable, S_IRUGO | S_IWUSR,
1160 i7core_inject_enable_show, i7core_inject_enable_store);
1161
1162static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
1163{
1164 struct i7core_pvt *pvt = mci->pvt_info;
1165 int rc;
1166
1167 rc = device_create_file(&mci->dev, &dev_attr_inject_section);
1168 if (rc < 0)
1169 return rc;
1170 rc = device_create_file(&mci->dev, &dev_attr_inject_type);
1171 if (rc < 0)
1172 return rc;
1173 rc = device_create_file(&mci->dev, &dev_attr_inject_eccmask);
1174 if (rc < 0)
1175 return rc;
1176 rc = device_create_file(&mci->dev, &dev_attr_inject_enable);
1177 if (rc < 0)
1178 return rc;
1179
1180 pvt->addrmatch_dev.type = &addrmatch_type;
1181 pvt->addrmatch_dev.bus = mci->dev.bus;
1182 device_initialize(&pvt->addrmatch_dev);
1183 pvt->addrmatch_dev.parent = &mci->dev;
1184 dev_set_name(&pvt->addrmatch_dev, "inject_addrmatch");
1185 dev_set_drvdata(&pvt->addrmatch_dev, mci);
1186
1187 debugf1("%s(): creating %s\n", __func__,
1188 dev_name(&pvt->addrmatch_dev));
1189
1190 rc = device_add(&pvt->addrmatch_dev);
1191 if (rc < 0)
1192 return rc;
1193
1194 if (!pvt->is_registered) {
1195 pvt->chancounts_dev.type = &all_channel_counts_type;
1196 pvt->chancounts_dev.bus = mci->dev.bus;
1197 device_initialize(&pvt->chancounts_dev);
1198 pvt->chancounts_dev.parent = &mci->dev;
1199 dev_set_name(&pvt->chancounts_dev, "all_channel_counts");
1200 dev_set_drvdata(&pvt->chancounts_dev, mci);
1201
1202 debugf1("%s(): creating %s\n", __func__,
1203 dev_name(&pvt->chancounts_dev));
1204
1205 rc = device_add(&pvt->chancounts_dev);
1206 if (rc < 0)
1207 return rc;
1208 }
1209 return 0;
1210}
1211
1212static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
1213{
1214 struct i7core_pvt *pvt = mci->pvt_info;
1215
1216 debugf1("\n");
1217
1218 device_remove_file(&mci->dev, &dev_attr_inject_section);
1219 device_remove_file(&mci->dev, &dev_attr_inject_type);
1220 device_remove_file(&mci->dev, &dev_attr_inject_eccmask);
1221 device_remove_file(&mci->dev, &dev_attr_inject_enable);
1222
1223 if (!pvt->is_registered) {
1224 put_device(&pvt->chancounts_dev);
1225 device_del(&pvt->chancounts_dev);
1226 }
1227 put_device(&pvt->addrmatch_dev);
1228 device_del(&pvt->addrmatch_dev);
1229}
1230
1155/**************************************************************************** 1231/****************************************************************************
1156 Device initialization routines: put/get, init/exit 1232 Device initialization routines: put/get, init/exit
1157 ****************************************************************************/ 1233 ****************************************************************************/
@@ -2122,6 +2198,7 @@ static void i7core_unregister_mci(struct i7core_dev *i7core_dev)
2122 i7core_pci_ctl_release(pvt); 2198 i7core_pci_ctl_release(pvt);
2123 2199
2124 /* Remove MC sysfs nodes */ 2200 /* Remove MC sysfs nodes */
2201 i7core_delete_sysfs_devices(mci);
2125 edac_mc_del_mc(mci->pdev); 2202 edac_mc_del_mc(mci->pdev);
2126 2203
2127 debugf1("%s: free mci struct\n", mci->ctl_name); 2204 debugf1("%s: free mci struct\n", mci->ctl_name);
@@ -2180,10 +2257,6 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev)
2180 if (unlikely(rc < 0)) 2257 if (unlikely(rc < 0))
2181 goto fail0; 2258 goto fail0;
2182 2259
2183 if (pvt->is_registered)
2184 mci->mc_driver_sysfs_attributes = i7core_sysfs_rdimm_attrs;
2185 else
2186 mci->mc_driver_sysfs_attributes = i7core_sysfs_udimm_attrs;
2187 2260
2188 /* Get dimm basic config */ 2261 /* Get dimm basic config */
2189 get_dimm_config(mci); 2262 get_dimm_config(mci);
@@ -2207,6 +2280,13 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev)
2207 rc = -EINVAL; 2280 rc = -EINVAL;
2208 goto fail0; 2281 goto fail0;
2209 } 2282 }
2283 if (i7core_create_sysfs_devices(mci)) {
2284 debugf0("MC: " __FILE__
2285 ": %s(): failed to create sysfs nodes\n", __func__);
2286 edac_mc_del_mc(mci->pdev);
2287 rc = -EINVAL;
2288 goto fail0;
2289 }
2210 2290
2211 /* Default error mask is any memory */ 2291 /* Default error mask is any memory */
2212 pvt->inject.channel = 0; 2292 pvt->inject.channel = 0;