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 |
