aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/edac/edac_mc.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 9037ffa100d5..d5dc9da7f99f 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -199,6 +199,36 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems)
199 return (void *)(((unsigned long)ptr) + align - r); 199 return (void *)(((unsigned long)ptr) + align - r);
200} 200}
201 201
202static void _edac_mc_free(struct mem_ctl_info *mci)
203{
204 int i, chn, row;
205 struct csrow_info *csr;
206 const unsigned int tot_dimms = mci->tot_dimms;
207 const unsigned int tot_channels = mci->num_cschannel;
208 const unsigned int tot_csrows = mci->nr_csrows;
209
210 if (mci->dimms) {
211 for (i = 0; i < tot_dimms; i++)
212 kfree(mci->dimms[i]);
213 kfree(mci->dimms);
214 }
215 if (mci->csrows) {
216 for (row = 0; row < tot_csrows; row++) {
217 csr = mci->csrows[row];
218 if (csr) {
219 if (csr->channels) {
220 for (chn = 0; chn < tot_channels; chn++)
221 kfree(csr->channels[chn]);
222 kfree(csr->channels);
223 }
224 kfree(csr);
225 }
226 }
227 kfree(mci->csrows);
228 }
229 kfree(mci);
230}
231
202/** 232/**
203 * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure 233 * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure
204 * @mc_num: Memory controller number 234 * @mc_num: Memory controller number
@@ -413,26 +443,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
413 return mci; 443 return mci;
414 444
415error: 445error:
416 if (mci->dimms) { 446 _edac_mc_free(mci);
417 for (i = 0; i < tot_dimms; i++)
418 kfree(mci->dimms[i]);
419 kfree(mci->dimms);
420 }
421 if (mci->csrows) {
422 for (row = 0; row < tot_csrows; row++) {
423 csr = mci->csrows[row];
424 if (csr) {
425 if (csr->channels) {
426 for (chn = 0; chn < tot_channels; chn++)
427 kfree(csr->channels[chn]);
428 kfree(csr->channels);
429 }
430 kfree(csr);
431 }
432 }
433 kfree(mci->csrows);
434 }
435 kfree(mci);
436 447
437 return NULL; 448 return NULL;
438} 449}
@@ -447,6 +458,14 @@ void edac_mc_free(struct mem_ctl_info *mci)
447{ 458{
448 edac_dbg(1, "\n"); 459 edac_dbg(1, "\n");
449 460
461 /* If we're not yet registered with sysfs free only what was allocated
462 * in edac_mc_alloc().
463 */
464 if (!device_is_registered(&mci->dev)) {
465 _edac_mc_free(mci);
466 return;
467 }
468
450 /* the mci instance is freed here, when the sysfs object is dropped */ 469 /* the mci instance is freed here, when the sysfs object is dropped */
451 edac_unregister_sysfs(mci); 470 edac_unregister_sysfs(mci);
452} 471}