diff options
-rw-r--r-- | drivers/edac/edac_mc.c | 9 | ||||
-rw-r--r-- | drivers/edac/edac_mc_sysfs.c | 28 | ||||
-rw-r--r-- | drivers/edac/i5100_edac.c | 2 | ||||
-rw-r--r-- | include/linux/edac.h | 7 |
4 files changed, 31 insertions, 15 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 27e86d938262..89e109022d78 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -48,6 +48,8 @@ static LIST_HEAD(mc_devices); | |||
48 | */ | 48 | */ |
49 | static void const *edac_mc_owner; | 49 | static void const *edac_mc_owner; |
50 | 50 | ||
51 | static struct bus_type mc_bus[EDAC_MAX_MCS]; | ||
52 | |||
51 | unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf, | 53 | unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf, |
52 | unsigned len) | 54 | unsigned len) |
53 | { | 55 | { |
@@ -723,6 +725,11 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) | |||
723 | int ret = -EINVAL; | 725 | int ret = -EINVAL; |
724 | edac_dbg(0, "\n"); | 726 | edac_dbg(0, "\n"); |
725 | 727 | ||
728 | if (mci->mc_idx >= EDAC_MAX_MCS) { | ||
729 | pr_warn_once("Too many memory controllers: %d\n", mci->mc_idx); | ||
730 | return -ENODEV; | ||
731 | } | ||
732 | |||
726 | #ifdef CONFIG_EDAC_DEBUG | 733 | #ifdef CONFIG_EDAC_DEBUG |
727 | if (edac_debug_level >= 3) | 734 | if (edac_debug_level >= 3) |
728 | edac_mc_dump_mci(mci); | 735 | edac_mc_dump_mci(mci); |
@@ -762,6 +769,8 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) | |||
762 | /* set load time so that error rate can be tracked */ | 769 | /* set load time so that error rate can be tracked */ |
763 | mci->start_time = jiffies; | 770 | mci->start_time = jiffies; |
764 | 771 | ||
772 | mci->bus = &mc_bus[mci->mc_idx]; | ||
773 | |||
765 | if (edac_create_sysfs_mci_device(mci)) { | 774 | if (edac_create_sysfs_mci_device(mci)) { |
766 | edac_mc_printk(mci, KERN_WARNING, | 775 | edac_mc_printk(mci, KERN_WARNING, |
767 | "failed to create sysfs device\n"); | 776 | "failed to create sysfs device\n"); |
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index ef15a7e613bc..e7c32c4f7837 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -370,7 +370,7 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci, | |||
370 | return -ENODEV; | 370 | return -ENODEV; |
371 | 371 | ||
372 | csrow->dev.type = &csrow_attr_type; | 372 | csrow->dev.type = &csrow_attr_type; |
373 | csrow->dev.bus = &mci->bus; | 373 | csrow->dev.bus = mci->bus; |
374 | device_initialize(&csrow->dev); | 374 | device_initialize(&csrow->dev); |
375 | csrow->dev.parent = &mci->dev; | 375 | csrow->dev.parent = &mci->dev; |
376 | csrow->mci = mci; | 376 | csrow->mci = mci; |
@@ -605,7 +605,7 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci, | |||
605 | dimm->mci = mci; | 605 | dimm->mci = mci; |
606 | 606 | ||
607 | dimm->dev.type = &dimm_attr_type; | 607 | dimm->dev.type = &dimm_attr_type; |
608 | dimm->dev.bus = &mci->bus; | 608 | dimm->dev.bus = mci->bus; |
609 | device_initialize(&dimm->dev); | 609 | device_initialize(&dimm->dev); |
610 | 610 | ||
611 | dimm->dev.parent = &mci->dev; | 611 | dimm->dev.parent = &mci->dev; |
@@ -975,11 +975,13 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | |||
975 | * The memory controller needs its own bus, in order to avoid | 975 | * The memory controller needs its own bus, in order to avoid |
976 | * namespace conflicts at /sys/bus/edac. | 976 | * namespace conflicts at /sys/bus/edac. |
977 | */ | 977 | */ |
978 | mci->bus.name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx); | 978 | mci->bus->name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx); |
979 | if (!mci->bus.name) | 979 | if (!mci->bus->name) |
980 | return -ENOMEM; | 980 | return -ENOMEM; |
981 | edac_dbg(0, "creating bus %s\n", mci->bus.name); | 981 | |
982 | err = bus_register(&mci->bus); | 982 | edac_dbg(0, "creating bus %s\n", mci->bus->name); |
983 | |||
984 | err = bus_register(mci->bus); | ||
983 | if (err < 0) | 985 | if (err < 0) |
984 | return err; | 986 | return err; |
985 | 987 | ||
@@ -988,7 +990,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | |||
988 | device_initialize(&mci->dev); | 990 | device_initialize(&mci->dev); |
989 | 991 | ||
990 | mci->dev.parent = mci_pdev; | 992 | mci->dev.parent = mci_pdev; |
991 | mci->dev.bus = &mci->bus; | 993 | mci->dev.bus = mci->bus; |
992 | dev_set_name(&mci->dev, "mc%d", mci->mc_idx); | 994 | dev_set_name(&mci->dev, "mc%d", mci->mc_idx); |
993 | dev_set_drvdata(&mci->dev, mci); | 995 | dev_set_drvdata(&mci->dev, mci); |
994 | pm_runtime_forbid(&mci->dev); | 996 | pm_runtime_forbid(&mci->dev); |
@@ -997,8 +999,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | |||
997 | err = device_add(&mci->dev); | 999 | err = device_add(&mci->dev); |
998 | if (err < 0) { | 1000 | if (err < 0) { |
999 | edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev)); | 1001 | edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev)); |
1000 | bus_unregister(&mci->bus); | 1002 | bus_unregister(mci->bus); |
1001 | kfree(mci->bus.name); | 1003 | kfree(mci->bus->name); |
1002 | return err; | 1004 | return err; |
1003 | } | 1005 | } |
1004 | 1006 | ||
@@ -1064,8 +1066,8 @@ fail: | |||
1064 | } | 1066 | } |
1065 | fail2: | 1067 | fail2: |
1066 | device_unregister(&mci->dev); | 1068 | device_unregister(&mci->dev); |
1067 | bus_unregister(&mci->bus); | 1069 | bus_unregister(mci->bus); |
1068 | kfree(mci->bus.name); | 1070 | kfree(mci->bus->name); |
1069 | return err; | 1071 | return err; |
1070 | } | 1072 | } |
1071 | 1073 | ||
@@ -1098,8 +1100,8 @@ void edac_unregister_sysfs(struct mem_ctl_info *mci) | |||
1098 | { | 1100 | { |
1099 | edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev)); | 1101 | edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev)); |
1100 | device_unregister(&mci->dev); | 1102 | device_unregister(&mci->dev); |
1101 | bus_unregister(&mci->bus); | 1103 | bus_unregister(mci->bus); |
1102 | kfree(mci->bus.name); | 1104 | kfree(mci->bus->name); |
1103 | } | 1105 | } |
1104 | 1106 | ||
1105 | static void mc_attr_release(struct device *dev) | 1107 | static void mc_attr_release(struct device *dev) |
diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c index 1b635178cc44..157b934e8ce3 100644 --- a/drivers/edac/i5100_edac.c +++ b/drivers/edac/i5100_edac.c | |||
@@ -974,7 +974,7 @@ static int i5100_setup_debugfs(struct mem_ctl_info *mci) | |||
974 | if (!i5100_debugfs) | 974 | if (!i5100_debugfs) |
975 | return -ENODEV; | 975 | return -ENODEV; |
976 | 976 | ||
977 | priv->debugfs = debugfs_create_dir(mci->bus.name, i5100_debugfs); | 977 | priv->debugfs = debugfs_create_dir(mci->bus->name, i5100_debugfs); |
978 | 978 | ||
979 | if (!priv->debugfs) | 979 | if (!priv->debugfs) |
980 | return -ENOMEM; | 980 | return -ENOMEM; |
diff --git a/include/linux/edac.h b/include/linux/edac.h index 0b763276f619..5c6d7fbaf89e 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h | |||
@@ -622,7 +622,7 @@ struct edac_raw_error_desc { | |||
622 | */ | 622 | */ |
623 | struct mem_ctl_info { | 623 | struct mem_ctl_info { |
624 | struct device dev; | 624 | struct device dev; |
625 | struct bus_type bus; | 625 | struct bus_type *bus; |
626 | 626 | ||
627 | struct list_head link; /* for global list of mem_ctl_info structs */ | 627 | struct list_head link; /* for global list of mem_ctl_info structs */ |
628 | 628 | ||
@@ -742,4 +742,9 @@ struct mem_ctl_info { | |||
742 | #endif | 742 | #endif |
743 | }; | 743 | }; |
744 | 744 | ||
745 | /* | ||
746 | * Maximum number of memory controllers in the coherent fabric. | ||
747 | */ | ||
748 | #define EDAC_MAX_MCS 16 | ||
749 | |||
745 | #endif | 750 | #endif |