diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-26 13:13:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-26 13:13:48 -0400 |
commit | da62aa69c181e3bd465a5c868ece166921a81e14 (patch) | |
tree | 5f1a3e234dd791099ba8761f79442b0ac6f664c0 /drivers/edac/edac_mc_sysfs.c | |
parent | f1ebdd60cc73ed36fd977f7e719ce70d2f5cd1c0 (diff) | |
parent | 76a7bd81130646459dfded1845e0d511488a6afa (diff) |
Merge branch 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/i7core
* 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/i7core: (34 commits)
i7core_edac: return -ENODEV when devices were already probed
i7core_edac: properly terminate pci_dev_table
i7core_edac: Avoid PCI refcount to reach zero on successive load/reload
i7core_edac: Fix refcount error at PCI devices
i7core_edac: it is safe to i7core_unregister_mci() when mci=NULL
i7core_edac: Fix an oops at i7core probe
i7core_edac: Remove unused member channels in i7core_pvt
i7core_edac: Remove unused arg csrow from get_dimm_config
i7core_edac: Reduce args of i7core_register_mci
i7core_edac: Introduce i7core_unregister_mci
i7core_edac: Use saved pointers
i7core_edac: Check probe counter in i7core_remove
i7core_edac: Call pci_dev_put() when alloc_i7core_dev() failed
i7core_edac: Fix error path of i7core_register_mci
i7core_edac: Fix order of lines in i7core_register_mci
i7core_edac: Always do get/put for all devices
i7core_edac: Introduce i7core_pci_ctl_create/release
i7core_edac: Introduce free_i7core_dev
i7core_edac: Introduce alloc_i7core_dev
i7core_edac: Reduce args of i7core_get_onedevice
...
Diffstat (limited to 'drivers/edac/edac_mc_sysfs.c')
-rw-r--r-- | drivers/edac/edac_mc_sysfs.c | 82 |
1 files changed, 46 insertions, 36 deletions
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index a4135860149b..dce61f7ba38b 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -631,9 +631,6 @@ static void edac_mci_control_release(struct kobject *kobj) | |||
631 | 631 | ||
632 | /* decrement the module ref count */ | 632 | /* decrement the module ref count */ |
633 | module_put(mci->owner); | 633 | module_put(mci->owner); |
634 | |||
635 | /* free the mci instance memory here */ | ||
636 | kfree(mci); | ||
637 | } | 634 | } |
638 | 635 | ||
639 | static struct kobj_type ktype_mci = { | 636 | static struct kobj_type ktype_mci = { |
@@ -713,6 +710,8 @@ fail_out: | |||
713 | */ | 710 | */ |
714 | void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) | 711 | void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) |
715 | { | 712 | { |
713 | debugf1("%s()\n", __func__); | ||
714 | |||
716 | /* delete the kobj from the mc_kset */ | 715 | /* delete the kobj from the mc_kset */ |
717 | kobject_put(&mci->edac_mci_kobj); | 716 | kobject_put(&mci->edac_mci_kobj); |
718 | } | 717 | } |
@@ -760,8 +759,6 @@ static void edac_inst_grp_release(struct kobject *kobj) | |||
760 | 759 | ||
761 | grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj); | 760 | grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj); |
762 | mci = grp->mci; | 761 | mci = grp->mci; |
763 | |||
764 | kobject_put(&mci->edac_mci_kobj); | ||
765 | } | 762 | } |
766 | 763 | ||
767 | /* Intermediate show/store table */ | 764 | /* Intermediate show/store table */ |
@@ -784,7 +781,7 @@ static struct kobj_type ktype_inst_grp = { | |||
784 | * object tree. | 781 | * object tree. |
785 | */ | 782 | */ |
786 | static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | 783 | static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, |
787 | struct mcidev_sysfs_attribute *sysfs_attrib, | 784 | const struct mcidev_sysfs_attribute *sysfs_attrib, |
788 | struct kobject *kobj) | 785 | struct kobject *kobj) |
789 | { | 786 | { |
790 | int err; | 787 | int err; |
@@ -792,6 +789,7 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |||
792 | debugf1("%s()\n", __func__); | 789 | debugf1("%s()\n", __func__); |
793 | 790 | ||
794 | while (sysfs_attrib) { | 791 | while (sysfs_attrib) { |
792 | debugf1("%s() sysfs_attrib = %p\n",__func__, sysfs_attrib); | ||
795 | if (sysfs_attrib->grp) { | 793 | if (sysfs_attrib->grp) { |
796 | struct mcidev_sysfs_group_kobj *grp_kobj; | 794 | struct mcidev_sysfs_group_kobj *grp_kobj; |
797 | 795 | ||
@@ -799,10 +797,9 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |||
799 | if (!grp_kobj) | 797 | if (!grp_kobj) |
800 | return -ENOMEM; | 798 | return -ENOMEM; |
801 | 799 | ||
802 | list_add_tail(&grp_kobj->list, &mci->grp_kobj_list); | ||
803 | |||
804 | grp_kobj->grp = sysfs_attrib->grp; | 800 | grp_kobj->grp = sysfs_attrib->grp; |
805 | grp_kobj->mci = mci; | 801 | grp_kobj->mci = mci; |
802 | list_add_tail(&grp_kobj->list, &mci->grp_kobj_list); | ||
806 | 803 | ||
807 | debugf0("%s() grp %s, mci %p\n", __func__, | 804 | debugf0("%s() grp %s, mci %p\n", __func__, |
808 | sysfs_attrib->grp->name, mci); | 805 | sysfs_attrib->grp->name, mci); |
@@ -811,26 +808,28 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |||
811 | &ktype_inst_grp, | 808 | &ktype_inst_grp, |
812 | &mci->edac_mci_kobj, | 809 | &mci->edac_mci_kobj, |
813 | sysfs_attrib->grp->name); | 810 | sysfs_attrib->grp->name); |
814 | if (err) | 811 | if (err < 0) { |
812 | printk(KERN_ERR "kobject_init_and_add failed: %d\n", err); | ||
815 | return err; | 813 | return err; |
816 | 814 | } | |
817 | err = edac_create_mci_instance_attributes(mci, | 815 | err = edac_create_mci_instance_attributes(mci, |
818 | grp_kobj->grp->mcidev_attr, | 816 | grp_kobj->grp->mcidev_attr, |
819 | &grp_kobj->kobj); | 817 | &grp_kobj->kobj); |
820 | 818 | ||
821 | if (err) | 819 | if (err < 0) |
822 | return err; | 820 | return err; |
823 | } else if (sysfs_attrib->attr.name) { | 821 | } else if (sysfs_attrib->attr.name) { |
824 | debugf0("%s() file %s\n", __func__, | 822 | debugf0("%s() file %s\n", __func__, |
825 | sysfs_attrib->attr.name); | 823 | sysfs_attrib->attr.name); |
826 | 824 | ||
827 | err = sysfs_create_file(kobj, &sysfs_attrib->attr); | 825 | err = sysfs_create_file(kobj, &sysfs_attrib->attr); |
826 | if (err < 0) { | ||
827 | printk(KERN_ERR "sysfs_create_file failed: %d\n", err); | ||
828 | return err; | ||
829 | } | ||
828 | } else | 830 | } else |
829 | break; | 831 | break; |
830 | 832 | ||
831 | if (err) { | ||
832 | return err; | ||
833 | } | ||
834 | sysfs_attrib++; | 833 | sysfs_attrib++; |
835 | } | 834 | } |
836 | 835 | ||
@@ -843,7 +842,7 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |||
843 | * directory of this mci instance. | 842 | * directory of this mci instance. |
844 | */ | 843 | */ |
845 | static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, | 844 | static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, |
846 | struct mcidev_sysfs_attribute *sysfs_attrib, | 845 | const struct mcidev_sysfs_attribute *sysfs_attrib, |
847 | struct kobject *kobj, int count) | 846 | struct kobject *kobj, int count) |
848 | { | 847 | { |
849 | struct mcidev_sysfs_group_kobj *grp_kobj, *tmp; | 848 | struct mcidev_sysfs_group_kobj *grp_kobj, *tmp; |
@@ -855,13 +854,24 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, | |||
855 | * Remove first all the atributes | 854 | * Remove first all the atributes |
856 | */ | 855 | */ |
857 | while (sysfs_attrib) { | 856 | while (sysfs_attrib) { |
857 | debugf1("%s() sysfs_attrib = %p\n",__func__, sysfs_attrib); | ||
858 | if (sysfs_attrib->grp) { | 858 | if (sysfs_attrib->grp) { |
859 | list_for_each_entry(grp_kobj, &mci->grp_kobj_list, | 859 | debugf1("%s() seeking for group %s\n", |
860 | list) | 860 | __func__, sysfs_attrib->grp->name); |
861 | if (grp_kobj->grp == sysfs_attrib->grp) | 861 | list_for_each_entry(grp_kobj, |
862 | &mci->grp_kobj_list, list) { | ||
863 | debugf1("%s() grp_kobj->grp = %p\n",__func__, grp_kobj->grp); | ||
864 | if (grp_kobj->grp == sysfs_attrib->grp) { | ||
862 | edac_remove_mci_instance_attributes(mci, | 865 | edac_remove_mci_instance_attributes(mci, |
863 | grp_kobj->grp->mcidev_attr, | 866 | grp_kobj->grp->mcidev_attr, |
864 | &grp_kobj->kobj, count + 1); | 867 | &grp_kobj->kobj, count + 1); |
868 | debugf0("%s() group %s\n", __func__, | ||
869 | sysfs_attrib->grp->name); | ||
870 | kobject_put(&grp_kobj->kobj); | ||
871 | } | ||
872 | } | ||
873 | debugf1("%s() end of seeking for group %s\n", | ||
874 | __func__, sysfs_attrib->grp->name); | ||
865 | } else if (sysfs_attrib->attr.name) { | 875 | } else if (sysfs_attrib->attr.name) { |
866 | debugf0("%s() file %s\n", __func__, | 876 | debugf0("%s() file %s\n", __func__, |
867 | sysfs_attrib->attr.name); | 877 | sysfs_attrib->attr.name); |
@@ -871,15 +881,14 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, | |||
871 | sysfs_attrib++; | 881 | sysfs_attrib++; |
872 | } | 882 | } |
873 | 883 | ||
874 | /* | 884 | /* Remove the group objects */ |
875 | * Now that all attributes got removed, it is save to remove all groups | 885 | if (count) |
876 | */ | 886 | return; |
877 | if (!count) | 887 | list_for_each_entry_safe(grp_kobj, tmp, |
878 | list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list, | 888 | &mci->grp_kobj_list, list) { |
879 | list) { | 889 | list_del(&grp_kobj->list); |
880 | debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name); | 890 | kfree(grp_kobj); |
881 | kobject_put(&grp_kobj->kobj); | 891 | } |
882 | } | ||
883 | } | 892 | } |
884 | 893 | ||
885 | 894 | ||
@@ -971,6 +980,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | |||
971 | debugf0("%s()\n", __func__); | 980 | debugf0("%s()\n", __func__); |
972 | 981 | ||
973 | /* remove all csrow kobjects */ | 982 | /* remove all csrow kobjects */ |
983 | debugf0("%s() unregister this mci kobj\n", __func__); | ||
974 | for (i = 0; i < mci->nr_csrows; i++) { | 984 | for (i = 0; i < mci->nr_csrows; i++) { |
975 | if (mci->csrows[i].nr_pages > 0) { | 985 | if (mci->csrows[i].nr_pages > 0) { |
976 | debugf0("%s() unreg csrow-%d\n", __func__, i); | 986 | debugf0("%s() unreg csrow-%d\n", __func__, i); |
@@ -978,20 +988,20 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | |||
978 | } | 988 | } |
979 | } | 989 | } |
980 | 990 | ||
981 | debugf0("%s() remove_link\n", __func__); | 991 | /* remove this mci instance's attribtes */ |
992 | if (mci->mc_driver_sysfs_attributes) { | ||
993 | debugf0("%s() unregister mci private attributes\n", __func__); | ||
994 | edac_remove_mci_instance_attributes(mci, | ||
995 | mci->mc_driver_sysfs_attributes, | ||
996 | &mci->edac_mci_kobj, 0); | ||
997 | } | ||
982 | 998 | ||
983 | /* remove the symlink */ | 999 | /* remove the symlink */ |
1000 | debugf0("%s() remove_link\n", __func__); | ||
984 | sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); | 1001 | sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); |
985 | 1002 | ||
986 | debugf0("%s() remove_mci_instance\n", __func__); | ||
987 | |||
988 | /* remove this mci instance's attribtes */ | ||
989 | edac_remove_mci_instance_attributes(mci, | ||
990 | mci->mc_driver_sysfs_attributes, | ||
991 | &mci->edac_mci_kobj, 0); | ||
992 | debugf0("%s() unregister this mci kobj\n", __func__); | ||
993 | |||
994 | /* unregister this instance's kobject */ | 1003 | /* unregister this instance's kobject */ |
1004 | debugf0("%s() remove_mci_instance\n", __func__); | ||
995 | kobject_put(&mci->edac_mci_kobj); | 1005 | kobject_put(&mci->edac_mci_kobj); |
996 | } | 1006 | } |
997 | 1007 | ||