diff options
Diffstat (limited to 'drivers/edac/edac_mc.c')
-rw-r--r-- | drivers/edac/edac_mc.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 6e4c94e9654a..2d53cb38868a 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -137,6 +137,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, | |||
137 | void *pvt; | 137 | void *pvt; |
138 | unsigned size; | 138 | unsigned size; |
139 | int row, chn; | 139 | int row, chn; |
140 | int err; | ||
140 | 141 | ||
141 | /* Figure out the offsets of the various items from the start of an mc | 142 | /* Figure out the offsets of the various items from the start of an mc |
142 | * structure. We want the alignment of each item to be at least as | 143 | * structure. We want the alignment of each item to be at least as |
@@ -149,7 +150,8 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, | |||
149 | pvt = edac_align_ptr(&chi[nr_chans * nr_csrows], sz_pvt); | 150 | pvt = edac_align_ptr(&chi[nr_chans * nr_csrows], sz_pvt); |
150 | size = ((unsigned long)pvt) + sz_pvt; | 151 | size = ((unsigned long)pvt) + sz_pvt; |
151 | 152 | ||
152 | if ((mci = kmalloc(size, GFP_KERNEL)) == NULL) | 153 | mci = kzalloc(size, GFP_KERNEL); |
154 | if (mci == NULL) | ||
153 | return NULL; | 155 | return NULL; |
154 | 156 | ||
155 | /* Adjust pointers so they point within the memory we just allocated | 157 | /* Adjust pointers so they point within the memory we just allocated |
@@ -182,20 +184,34 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, | |||
182 | 184 | ||
183 | mci->op_state = OP_ALLOC; | 185 | mci->op_state = OP_ALLOC; |
184 | 186 | ||
187 | /* | ||
188 | * Initialize the 'root' kobj for the edac_mc controller | ||
189 | */ | ||
190 | err = edac_mc_register_sysfs_main_kobj(mci); | ||
191 | if (err) { | ||
192 | kfree(mci); | ||
193 | return NULL; | ||
194 | } | ||
195 | |||
196 | /* at this point, the root kobj is valid, and in order to | ||
197 | * 'free' the object, then the function: | ||
198 | * edac_mc_unregister_sysfs_main_kobj() must be called | ||
199 | * which will perform kobj unregistration and the actual free | ||
200 | * will occur during the kobject callback operation | ||
201 | */ | ||
185 | return mci; | 202 | return mci; |
186 | } | 203 | } |
187 | |||
188 | EXPORT_SYMBOL_GPL(edac_mc_alloc); | 204 | EXPORT_SYMBOL_GPL(edac_mc_alloc); |
189 | 205 | ||
190 | /** | 206 | /** |
191 | * edac_mc_free: Free a previously allocated 'mci' structure | 207 | * edac_mc_free |
208 | * 'Free' a previously allocated 'mci' structure | ||
192 | * @mci: pointer to a struct mem_ctl_info structure | 209 | * @mci: pointer to a struct mem_ctl_info structure |
193 | */ | 210 | */ |
194 | void edac_mc_free(struct mem_ctl_info *mci) | 211 | void edac_mc_free(struct mem_ctl_info *mci) |
195 | { | 212 | { |
196 | kfree(mci); | 213 | edac_mc_unregister_sysfs_main_kobj(mci); |
197 | } | 214 | } |
198 | |||
199 | EXPORT_SYMBOL_GPL(edac_mc_free); | 215 | EXPORT_SYMBOL_GPL(edac_mc_free); |
200 | 216 | ||
201 | static struct mem_ctl_info *find_mci_by_dev(struct device *dev) | 217 | static struct mem_ctl_info *find_mci_by_dev(struct device *dev) |
@@ -391,7 +407,6 @@ struct mem_ctl_info *edac_mc_find(int idx) | |||
391 | 407 | ||
392 | return NULL; | 408 | return NULL; |
393 | } | 409 | } |
394 | |||
395 | EXPORT_SYMBOL(edac_mc_find); | 410 | EXPORT_SYMBOL(edac_mc_find); |
396 | 411 | ||
397 | /** | 412 | /** |
@@ -465,7 +480,6 @@ fail0: | |||
465 | mutex_unlock(&mem_ctls_mutex); | 480 | mutex_unlock(&mem_ctls_mutex); |
466 | return 1; | 481 | return 1; |
467 | } | 482 | } |
468 | |||
469 | EXPORT_SYMBOL_GPL(edac_mc_add_mc); | 483 | EXPORT_SYMBOL_GPL(edac_mc_add_mc); |
470 | 484 | ||
471 | /** | 485 | /** |
@@ -501,7 +515,6 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev) | |||
501 | mci->mod_name, mci->ctl_name, dev_name(mci)); | 515 | mci->mod_name, mci->ctl_name, dev_name(mci)); |
502 | return mci; | 516 | return mci; |
503 | } | 517 | } |
504 | |||
505 | EXPORT_SYMBOL_GPL(edac_mc_del_mc); | 518 | EXPORT_SYMBOL_GPL(edac_mc_del_mc); |
506 | 519 | ||
507 | static void edac_mc_scrub_block(unsigned long page, unsigned long offset, | 520 | static void edac_mc_scrub_block(unsigned long page, unsigned long offset, |
@@ -571,7 +584,6 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page) | |||
571 | 584 | ||
572 | return row; | 585 | return row; |
573 | } | 586 | } |
574 | |||
575 | EXPORT_SYMBOL_GPL(edac_mc_find_csrow_by_page); | 587 | EXPORT_SYMBOL_GPL(edac_mc_find_csrow_by_page); |
576 | 588 | ||
577 | /* FIXME - setable log (warning/emerg) levels */ | 589 | /* FIXME - setable log (warning/emerg) levels */ |
@@ -636,7 +648,6 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, | |||
636 | mci->csrows[row].grain); | 648 | mci->csrows[row].grain); |
637 | } | 649 | } |
638 | } | 650 | } |
639 | |||
640 | EXPORT_SYMBOL_GPL(edac_mc_handle_ce); | 651 | EXPORT_SYMBOL_GPL(edac_mc_handle_ce); |
641 | 652 | ||
642 | void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) | 653 | void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) |
@@ -648,7 +659,6 @@ void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) | |||
648 | mci->ce_noinfo_count++; | 659 | mci->ce_noinfo_count++; |
649 | mci->ce_count++; | 660 | mci->ce_count++; |
650 | } | 661 | } |
651 | |||
652 | EXPORT_SYMBOL_GPL(edac_mc_handle_ce_no_info); | 662 | EXPORT_SYMBOL_GPL(edac_mc_handle_ce_no_info); |
653 | 663 | ||
654 | void edac_mc_handle_ue(struct mem_ctl_info *mci, | 664 | void edac_mc_handle_ue(struct mem_ctl_info *mci, |
@@ -702,7 +712,6 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci, | |||
702 | mci->ue_count++; | 712 | mci->ue_count++; |
703 | mci->csrows[row].ue_count++; | 713 | mci->csrows[row].ue_count++; |
704 | } | 714 | } |
705 | |||
706 | EXPORT_SYMBOL_GPL(edac_mc_handle_ue); | 715 | EXPORT_SYMBOL_GPL(edac_mc_handle_ue); |
707 | 716 | ||
708 | void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) | 717 | void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) |
@@ -716,7 +725,6 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) | |||
716 | mci->ue_noinfo_count++; | 725 | mci->ue_noinfo_count++; |
717 | mci->ue_count++; | 726 | mci->ue_count++; |
718 | } | 727 | } |
719 | |||
720 | EXPORT_SYMBOL_GPL(edac_mc_handle_ue_no_info); | 728 | EXPORT_SYMBOL_GPL(edac_mc_handle_ue_no_info); |
721 | 729 | ||
722 | /************************************************************* | 730 | /************************************************************* |
@@ -784,7 +792,6 @@ void edac_mc_handle_fbd_ue(struct mem_ctl_info *mci, | |||
784 | "labels \"%s\": %s\n", csrow, channela, | 792 | "labels \"%s\": %s\n", csrow, channela, |
785 | channelb, labels, msg); | 793 | channelb, labels, msg); |
786 | } | 794 | } |
787 | |||
788 | EXPORT_SYMBOL(edac_mc_handle_fbd_ue); | 795 | EXPORT_SYMBOL(edac_mc_handle_fbd_ue); |
789 | 796 | ||
790 | /************************************************************* | 797 | /************************************************************* |
@@ -824,7 +831,6 @@ void edac_mc_handle_fbd_ce(struct mem_ctl_info *mci, | |||
824 | mci->csrows[csrow].ce_count++; | 831 | mci->csrows[csrow].ce_count++; |
825 | mci->csrows[csrow].channels[channel].ce_count++; | 832 | mci->csrows[csrow].channels[channel].ce_count++; |
826 | } | 833 | } |
827 | |||
828 | EXPORT_SYMBOL(edac_mc_handle_fbd_ce); | 834 | EXPORT_SYMBOL(edac_mc_handle_fbd_ce); |
829 | 835 | ||
830 | /* | 836 | /* |