diff options
| -rw-r--r-- | drivers/edac/edac_mc.c | 1 | ||||
| -rw-r--r-- | drivers/edac/edac_mc_sysfs.c | 71 |
2 files changed, 43 insertions, 29 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 6b7e723e46be..b10b45cc7870 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
| @@ -207,6 +207,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, | |||
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | mci->op_state = OP_ALLOC; | 209 | mci->op_state = OP_ALLOC; |
| 210 | INIT_LIST_HEAD(&mci->grp_kobj_list); | ||
| 210 | 211 | ||
| 211 | /* | 212 | /* |
| 212 | * Initialize the 'root' kobj for the edac_mc controller | 213 | * Initialize the 'root' kobj for the edac_mc controller |
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index aacffe5d0f33..5a5734c1f6a5 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
| @@ -791,6 +791,7 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |||
| 791 | debugf1("%s()\n", __func__); | 791 | debugf1("%s()\n", __func__); |
| 792 | 792 | ||
| 793 | while (sysfs_attrib) { | 793 | while (sysfs_attrib) { |
| 794 | debugf1("%s() sysfs_attrib = %p\n",__func__, sysfs_attrib); | ||
| 794 | if (sysfs_attrib->grp) { | 795 | if (sysfs_attrib->grp) { |
| 795 | struct mcidev_sysfs_group_kobj *grp_kobj; | 796 | struct mcidev_sysfs_group_kobj *grp_kobj; |
| 796 | 797 | ||
| @@ -798,10 +799,9 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |||
| 798 | if (!grp_kobj) | 799 | if (!grp_kobj) |
| 799 | return -ENOMEM; | 800 | return -ENOMEM; |
| 800 | 801 | ||
| 801 | list_add_tail(&grp_kobj->list, &mci->grp_kobj_list); | ||
| 802 | |||
| 803 | grp_kobj->grp = sysfs_attrib->grp; | 802 | grp_kobj->grp = sysfs_attrib->grp; |
| 804 | grp_kobj->mci = mci; | 803 | grp_kobj->mci = mci; |
| 804 | list_add_tail(&grp_kobj->list, &mci->grp_kobj_list); | ||
| 805 | 805 | ||
| 806 | debugf0("%s() grp %s, mci %p\n", __func__, | 806 | debugf0("%s() grp %s, mci %p\n", __func__, |
| 807 | sysfs_attrib->grp->name, mci); | 807 | sysfs_attrib->grp->name, mci); |
| @@ -810,26 +810,28 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |||
| 810 | &ktype_inst_grp, | 810 | &ktype_inst_grp, |
| 811 | &mci->edac_mci_kobj, | 811 | &mci->edac_mci_kobj, |
| 812 | sysfs_attrib->grp->name); | 812 | sysfs_attrib->grp->name); |
| 813 | if (err) | 813 | if (err < 0) { |
| 814 | printk(KERN_ERR "kobject_init_and_add failed: %d\n", err); | ||
| 814 | return err; | 815 | return err; |
| 815 | 816 | } | |
| 816 | err = edac_create_mci_instance_attributes(mci, | 817 | err = edac_create_mci_instance_attributes(mci, |
| 817 | grp_kobj->grp->mcidev_attr, | 818 | grp_kobj->grp->mcidev_attr, |
| 818 | &grp_kobj->kobj); | 819 | &grp_kobj->kobj); |
| 819 | 820 | ||
| 820 | if (err) | 821 | if (err < 0) |
| 821 | return err; | 822 | return err; |
| 822 | } else if (sysfs_attrib->attr.name) { | 823 | } else if (sysfs_attrib->attr.name) { |
| 823 | debugf0("%s() file %s\n", __func__, | 824 | debugf0("%s() file %s\n", __func__, |
| 824 | sysfs_attrib->attr.name); | 825 | sysfs_attrib->attr.name); |
| 825 | 826 | ||
| 826 | err = sysfs_create_file(kobj, &sysfs_attrib->attr); | 827 | err = sysfs_create_file(kobj, &sysfs_attrib->attr); |
| 828 | if (err < 0) { | ||
| 829 | printk(KERN_ERR "sysfs_create_file failed: %d\n", err); | ||
| 830 | return err; | ||
| 831 | } | ||
| 827 | } else | 832 | } else |
| 828 | break; | 833 | break; |
| 829 | 834 | ||
| 830 | if (err) { | ||
| 831 | return err; | ||
| 832 | } | ||
| 833 | sysfs_attrib++; | 835 | sysfs_attrib++; |
| 834 | } | 836 | } |
| 835 | 837 | ||
| @@ -854,13 +856,24 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, | |||
| 854 | * Remove first all the atributes | 856 | * Remove first all the atributes |
| 855 | */ | 857 | */ |
| 856 | while (sysfs_attrib) { | 858 | while (sysfs_attrib) { |
| 859 | debugf1("%s() sysfs_attrib = %p\n",__func__, sysfs_attrib); | ||
| 857 | if (sysfs_attrib->grp) { | 860 | if (sysfs_attrib->grp) { |
| 858 | list_for_each_entry(grp_kobj, &mci->grp_kobj_list, | 861 | debugf1("%s() seeking for group %s\n", |
| 859 | list) | 862 | __func__, sysfs_attrib->grp->name); |
| 860 | if (grp_kobj->grp == sysfs_attrib->grp) | 863 | list_for_each_entry(grp_kobj, |
| 864 | &mci->grp_kobj_list, list) { | ||
| 865 | debugf1("%s() grp_kobj->grp = %p\n",__func__, grp_kobj->grp); | ||
| 866 | if (grp_kobj->grp == sysfs_attrib->grp) { | ||
| 861 | edac_remove_mci_instance_attributes(mci, | 867 | edac_remove_mci_instance_attributes(mci, |
| 862 | grp_kobj->grp->mcidev_attr, | 868 | grp_kobj->grp->mcidev_attr, |
| 863 | &grp_kobj->kobj, count + 1); | 869 | &grp_kobj->kobj, count + 1); |
| 870 | debugf0("%s() group %s\n", __func__, | ||
| 871 | sysfs_attrib->grp->name); | ||
| 872 | kobject_put(&grp_kobj->kobj); | ||
| 873 | } | ||
| 874 | } | ||
| 875 | debugf1("%s() end of seeking for group %s\n", | ||
| 876 | __func__, sysfs_attrib->grp->name); | ||
| 864 | } else if (sysfs_attrib->attr.name) { | 877 | } else if (sysfs_attrib->attr.name) { |
| 865 | debugf0("%s() file %s\n", __func__, | 878 | debugf0("%s() file %s\n", __func__, |
| 866 | sysfs_attrib->attr.name); | 879 | sysfs_attrib->attr.name); |
| @@ -870,15 +883,14 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, | |||
| 870 | sysfs_attrib++; | 883 | sysfs_attrib++; |
| 871 | } | 884 | } |
| 872 | 885 | ||
| 873 | /* | 886 | /* Remove the group objects */ |
| 874 | * Now that all attributes got removed, it is save to remove all groups | 887 | if (count) |
| 875 | */ | 888 | return; |
| 876 | if (!count) | 889 | list_for_each_entry_safe(grp_kobj, tmp, |
| 877 | list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list, | 890 | &mci->grp_kobj_list, list) { |
| 878 | list) { | 891 | list_del(&grp_kobj->list); |
| 879 | debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name); | 892 | kfree(grp_kobj); |
| 880 | kobject_put(&grp_kobj->kobj); | 893 | } |
| 881 | } | ||
| 882 | } | 894 | } |
| 883 | 895 | ||
| 884 | 896 | ||
| @@ -970,6 +982,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | |||
| 970 | debugf0("%s()\n", __func__); | 982 | debugf0("%s()\n", __func__); |
| 971 | 983 | ||
| 972 | /* remove all csrow kobjects */ | 984 | /* remove all csrow kobjects */ |
| 985 | debugf0("%s() unregister this mci kobj\n", __func__); | ||
| 973 | for (i = 0; i < mci->nr_csrows; i++) { | 986 | for (i = 0; i < mci->nr_csrows; i++) { |
| 974 | if (mci->csrows[i].nr_pages > 0) { | 987 | if (mci->csrows[i].nr_pages > 0) { |
| 975 | debugf0("%s() unreg csrow-%d\n", __func__, i); | 988 | debugf0("%s() unreg csrow-%d\n", __func__, i); |
| @@ -977,20 +990,20 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | |||
| 977 | } | 990 | } |
| 978 | } | 991 | } |
| 979 | 992 | ||
| 980 | debugf0("%s() remove_link\n", __func__); | 993 | /* remove this mci instance's attribtes */ |
| 994 | if (mci->mc_driver_sysfs_attributes) { | ||
| 995 | debugf0("%s() unregister mci private attributes\n", __func__); | ||
| 996 | edac_remove_mci_instance_attributes(mci, | ||
| 997 | mci->mc_driver_sysfs_attributes, | ||
| 998 | &mci->edac_mci_kobj, 0); | ||
| 999 | } | ||
| 981 | 1000 | ||
| 982 | /* remove the symlink */ | 1001 | /* remove the symlink */ |
| 1002 | debugf0("%s() remove_link\n", __func__); | ||
| 983 | sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); | 1003 | sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); |
| 984 | 1004 | ||
| 985 | debugf0("%s() remove_mci_instance\n", __func__); | ||
| 986 | |||
| 987 | /* remove this mci instance's attribtes */ | ||
| 988 | edac_remove_mci_instance_attributes(mci, | ||
| 989 | mci->mc_driver_sysfs_attributes, | ||
| 990 | &mci->edac_mci_kobj, 0); | ||
| 991 | debugf0("%s() unregister this mci kobj\n", __func__); | ||
| 992 | |||
| 993 | /* unregister this instance's kobject */ | 1005 | /* unregister this instance's kobject */ |
| 1006 | debugf0("%s() remove_mci_instance\n", __func__); | ||
| 994 | kobject_put(&mci->edac_mci_kobj); | 1007 | kobject_put(&mci->edac_mci_kobj); |
| 995 | } | 1008 | } |
| 996 | 1009 | ||
