aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-09-25 12:42:25 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-10 10:49:30 -0400
commitb968759ee7102f86fec5f3349f7a8ab4556884a3 (patch)
treedcea622a061de20fee0e64b8224e323a1fa5b4b1 /drivers/edac
parent35be95446734cbb10b088a6b38269ac4a8ac3a86 (diff)
edac: Create an unique instance for each kobj
Current code only works when there's just one memory controller, since we need one kobj for each instance. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/edac_core.h21
-rw-r--r--drivers/edac/edac_mc_sysfs.c75
2 files changed, 64 insertions, 32 deletions
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 02bbbc9696d9..efca9343d26a 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -342,23 +342,29 @@ struct csrow_info {
342}; 342};
343 343
344struct mcidev_sysfs_group { 344struct mcidev_sysfs_group {
345 const char *name; 345 const char *name; /* group name */
346 struct mcidev_sysfs_attribute *mcidev_attr; 346 struct mcidev_sysfs_attribute *mcidev_attr; /* group attributes */
347 struct kobject kobj; 347};
348
349struct mcidev_sysfs_group_kobj {
350 struct list_head list; /* list for all instances within a mc */
351
352 struct kobject kobj; /* kobj for the group */
348 353
354 struct mcidev_sysfs_group *grp; /* group description table */
349 struct mem_ctl_info *mci; /* the parent */ 355 struct mem_ctl_info *mci; /* the parent */
350}; 356};
351 357
352
353/* mcidev_sysfs_attribute structure 358/* mcidev_sysfs_attribute structure
354 * used for driver sysfs attributes and in mem_ctl_info 359 * used for driver sysfs attributes and in mem_ctl_info
355 * sysfs top level entries 360 * sysfs top level entries
356 */ 361 */
357struct mcidev_sysfs_attribute { 362struct mcidev_sysfs_attribute {
363 /* It should use either attr or grp */
358 struct attribute attr; 364 struct attribute attr;
365 struct mcidev_sysfs_group *grp; /* Points to a group of attributes */
359 366
360 struct mcidev_sysfs_group *grp; 367 /* Ops for show/store values at the attribute - not used on group */
361
362 ssize_t (*show)(struct mem_ctl_info *,char *); 368 ssize_t (*show)(struct mem_ctl_info *,char *);
363 ssize_t (*store)(struct mem_ctl_info *, const char *,size_t); 369 ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
364}; 370};
@@ -436,6 +442,9 @@ struct mem_ctl_info {
436 /* edac sysfs device control */ 442 /* edac sysfs device control */
437 struct kobject edac_mci_kobj; 443 struct kobject edac_mci_kobj;
438 444
445 /* list for all grp instances within a mc */
446 struct list_head grp_kobj_list;
447
439 /* Additional top controller level attributes, but specified 448 /* Additional top controller level attributes, but specified
440 * by the low level driver. 449 * by the low level driver.
441 * 450 *
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index f689d7d6ab46..c200c2fd43ea 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -730,7 +730,7 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci)
730 730
731#define EDAC_DEVICE_SYMLINK "device" 731#define EDAC_DEVICE_SYMLINK "device"
732 732
733#define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group, kobj)->mci) 733#define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group_kobj, kobj)->mci)
734 734
735/* MCI show/store functions for top most object */ 735/* MCI show/store functions for top most object */
736static ssize_t inst_grp_show(struct kobject *kobj, struct attribute *attr, 736static ssize_t inst_grp_show(struct kobject *kobj, struct attribute *attr,
@@ -764,12 +764,12 @@ static ssize_t inst_grp_store(struct kobject *kobj, struct attribute *attr,
764/* No memory to release for this kobj */ 764/* No memory to release for this kobj */
765static void edac_inst_grp_release(struct kobject *kobj) 765static void edac_inst_grp_release(struct kobject *kobj)
766{ 766{
767 struct mcidev_sysfs_group *grp; 767 struct mcidev_sysfs_group_kobj *grp;
768 struct mem_ctl_info *mci; 768 struct mem_ctl_info *mci;
769 769
770 debugf1("%s()\n", __func__); 770 debugf1("%s()\n", __func__);
771 771
772 grp = container_of(kobj, struct mcidev_sysfs_group, kobj); 772 grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj);
773 mci = grp->mci; 773 mci = grp->mci;
774 774
775 kobject_put(&mci->edac_mci_kobj); 775 kobject_put(&mci->edac_mci_kobj);
@@ -804,22 +804,30 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
804 804
805 while (sysfs_attrib) { 805 while (sysfs_attrib) {
806 if (sysfs_attrib->grp) { 806 if (sysfs_attrib->grp) {
807 struct kobject *newkobj = &sysfs_attrib->grp->kobj; 807 struct mcidev_sysfs_group_kobj *grp_kobj;
808
809 grp_kobj = kzalloc(sizeof(*grp_kobj), GFP_KERNEL);
810 if (!grp_kobj)
811 return -ENOMEM;
812
813 list_add_tail(&grp_kobj->list, &mci->grp_kobj_list);
814
815 grp_kobj->grp = sysfs_attrib->grp;
816 grp_kobj->mci = mci;
808 817
809 debugf0("%s() grp %s, mci %p\n", __func__, 818 debugf0("%s() grp %s, mci %p\n", __func__,
810 sysfs_attrib->grp->name, mci); 819 sysfs_attrib->grp->name, mci);
811 820
812 sysfs_attrib->grp->mci = mci; 821 err = kobject_init_and_add(&grp_kobj->kobj,
813 822 &ktype_inst_grp,
814 err = kobject_init_and_add(newkobj, &ktype_inst_grp,
815 &mci->edac_mci_kobj, 823 &mci->edac_mci_kobj,
816 sysfs_attrib->grp->name); 824 sysfs_attrib->grp->name);
817 if (err) 825 if (err)
818 return err; 826 return err;
819 827
820 err = edac_create_mci_instance_attributes(mci, 828 err = edac_create_mci_instance_attributes(mci,
821 sysfs_attrib->grp->mcidev_attr, 829 grp_kobj->grp->mcidev_attr,
822 newkobj); 830 &grp_kobj->kobj);
823 831
824 if (err) 832 if (err)
825 return err; 833 return err;
@@ -845,25 +853,27 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
845 * remove MC driver specific attributes at the topmost level 853 * remove MC driver specific attributes at the topmost level
846 * directory of this mci instance. 854 * directory of this mci instance.
847 */ 855 */
848static void edac_remove_mci_instance_attributes( 856static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci,
849 struct mcidev_sysfs_attribute *sysfs_attrib, 857 struct mcidev_sysfs_attribute *sysfs_attrib,
850 struct kobject *kobj) 858 struct kobject *kobj, int count)
851{ 859{
860 struct mcidev_sysfs_group_kobj *grp_kobj, *tmp;
861
852 debugf1("%s()\n", __func__); 862 debugf1("%s()\n", __func__);
853 863
854 /* loop if there are attributes and until we hit a NULL entry */ 864 /*
865 * loop if there are attributes and until we hit a NULL entry
866 * Remove first all the atributes
867 */
855 while (sysfs_attrib) { 868 while (sysfs_attrib) {
856 if (sysfs_attrib->grp) { 869 if (sysfs_attrib->grp) {
857 struct kobject *newkobj = &sysfs_attrib->grp->kobj; 870 list_for_each_entry(grp_kobj, &mci->grp_kobj_list,
858 871 list)
859 debugf0("%s() grp %s\n", __func__, 872 if (grp_kobj->grp == sysfs_attrib->grp)
860 sysfs_attrib->grp->name); 873 edac_remove_mci_instance_attributes(mci,
861 874 grp_kobj->grp->mcidev_attr,
862 edac_remove_mci_instance_attributes( 875 &grp_kobj->kobj, count + 1);
863 sysfs_attrib->grp->mcidev_attr, newkobj); 876 } else if (sysfs_attrib->attr.name) {
864
865 kobject_put(newkobj);
866 } else if (sysfs_attrib->attr.name) {
867 debugf0("%s() file %s\n", __func__, 877 debugf0("%s() file %s\n", __func__,
868 sysfs_attrib->attr.name); 878 sysfs_attrib->attr.name);
869 sysfs_remove_file(kobj, &sysfs_attrib->attr); 879 sysfs_remove_file(kobj, &sysfs_attrib->attr);
@@ -871,6 +881,16 @@ static void edac_remove_mci_instance_attributes(
871 break; 881 break;
872 sysfs_attrib++; 882 sysfs_attrib++;
873 } 883 }
884
885 /*
886 * Now that all attributes got removed, it is save to remove all groups
887 */
888 if (!count)
889 list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list,
890 list) {
891 debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name);
892 kobject_put(&grp_kobj->kobj);
893 }
874} 894}
875 895
876 896
@@ -891,6 +911,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
891 911
892 debugf0("%s() idx=%d\n", __func__, mci->mc_idx); 912 debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
893 913
914 INIT_LIST_HEAD(&mci->grp_kobj_list);
915
894 /* create a symlink for the device */ 916 /* create a symlink for the device */
895 err = sysfs_create_link(kobj_mci, &mci->dev->kobj, 917 err = sysfs_create_link(kobj_mci, &mci->dev->kobj,
896 EDAC_DEVICE_SYMLINK); 918 EDAC_DEVICE_SYMLINK);
@@ -940,8 +962,8 @@ fail1:
940 } 962 }
941 963
942 /* remove the mci instance's attributes, if any */ 964 /* remove the mci instance's attributes, if any */
943 edac_remove_mci_instance_attributes( 965 edac_remove_mci_instance_attributes(mci,
944 mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj); 966 mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj, 0);
945 967
946 /* remove the symlink */ 968 /* remove the symlink */
947 sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK); 969 sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK);
@@ -975,8 +997,9 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
975 debugf0("%s() remove_mci_instance\n", __func__); 997 debugf0("%s() remove_mci_instance\n", __func__);
976 998
977 /* remove this mci instance's attribtes */ 999 /* remove this mci instance's attribtes */
978 edac_remove_mci_instance_attributes(mci->mc_driver_sysfs_attributes, 1000 edac_remove_mci_instance_attributes(mci,
979 &mci->edac_mci_kobj); 1001 mci->mc_driver_sysfs_attributes,
1002 &mci->edac_mci_kobj, 0);
980 debugf0("%s() unregister this mci kobj\n", __func__); 1003 debugf0("%s() unregister this mci kobj\n", __func__);
981 1004
982 /* unregister this instance's kobject */ 1005 /* unregister this instance's kobject */