aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/edac_core.h12
-rw-r--r--drivers/edac/edac_mc_sysfs.c83
2 files changed, 67 insertions, 28 deletions
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 001b2e797fb3..97071ff1d22d 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -341,12 +341,22 @@ struct csrow_info {
341 struct channel_info *channels; 341 struct channel_info *channels;
342}; 342};
343 343
344struct mcidev_sysfs_group {
345 const char *name;
346 struct mcidev_sysfs_attribute *mcidev_attr;
347 struct kobject kobj;
348};
349
350
344/* mcidev_sysfs_attribute structure 351/* mcidev_sysfs_attribute structure
345 * used for driver sysfs attributes and in mem_ctl_info 352 * used for driver sysfs attributes and in mem_ctl_info
346 * sysfs top level entries 353 * sysfs top level entries
347 */ 354 */
348struct mcidev_sysfs_attribute { 355struct mcidev_sysfs_attribute {
349 struct attribute attr; 356 struct attribute attr;
357
358 struct mcidev_sysfs_group *grp;
359
350 ssize_t (*show)(struct mem_ctl_info *,char *); 360 ssize_t (*show)(struct mem_ctl_info *,char *);
351 ssize_t (*store)(struct mem_ctl_info *, const char *,size_t); 361 ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
352}; 362};
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 418b65f1a1da..655aa1a1f4f9 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -728,26 +728,43 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci)
728 728
729/* 729/*
730 * edac_create_mci_instance_attributes 730 * edac_create_mci_instance_attributes
731 * create MC driver specific attributes at the topmost level 731 * create MC driver specific attributes bellow an specified kobj
732 * directory of this mci instance. 732 * This routine calls itself recursively, in order to create an entire
733 * object tree.
733 */ 734 */
734static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci) 735static int edac_create_mci_instance_attributes(
736 struct mcidev_sysfs_attribute *sysfs_attrib,
737 struct kobject *kobj)
735{ 738{
736 int err; 739 int err;
737 struct mcidev_sysfs_attribute *sysfs_attrib;
738 740
739 /* point to the start of the array and iterate over it 741 while (sysfs_attrib) {
740 * adding each attribute listed to this mci instance's kobject 742 if (sysfs_attrib->grp) {
741 */ 743 struct kobject *newkobj = &sysfs_attrib->grp->kobj;
742 sysfs_attrib = mci->mc_driver_sysfs_attributes; 744 debugf0("%s() grp %s\n", __func__,
745 sysfs_attrib->grp->name);
746
747 err = kobject_init_and_add(newkobj, NULL,
748 kobj,
749 sysfs_attrib->grp->name);
750 if (err)
751 return err;
752
753 err = edac_create_mci_instance_attributes(
754 sysfs_attrib->grp->mcidev_attr, newkobj);
755 if (err)
756 return err;
757 } else if (sysfs_attrib->attr.name) {
758 debugf0("%s() file %s\n", __func__,
759 sysfs_attrib->attr.name);
760
761 err = sysfs_create_file(kobj, &sysfs_attrib->attr);
762 } else
763 break;
743 764
744 while (sysfs_attrib && sysfs_attrib->attr.name) {
745 err = sysfs_create_file(&mci->edac_mci_kobj,
746 (struct attribute*) sysfs_attrib);
747 if (err) { 765 if (err) {
748 return err; 766 return err;
749 } 767 }
750
751 sysfs_attrib++; 768 sysfs_attrib++;
752 } 769 }
753 770
@@ -759,19 +776,28 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci)
759 * remove MC driver specific attributes at the topmost level 776 * remove MC driver specific attributes at the topmost level
760 * directory of this mci instance. 777 * directory of this mci instance.
761 */ 778 */
762static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci) 779static void edac_remove_mci_instance_attributes(
780 struct mcidev_sysfs_attribute *sysfs_attrib,
781 struct kobject *kobj)
763{ 782{
764 struct mcidev_sysfs_attribute *sysfs_attrib;
765
766 /* point to the start of the array and iterate over it
767 * adding each attribute listed to this mci instance's kobject
768 */
769 sysfs_attrib = mci->mc_driver_sysfs_attributes;
770
771 /* loop if there are attributes and until we hit a NULL entry */ 783 /* loop if there are attributes and until we hit a NULL entry */
772 while (sysfs_attrib && sysfs_attrib->attr.name) { 784 while (sysfs_attrib) {
773 sysfs_remove_file(&mci->edac_mci_kobj, 785 if (sysfs_attrib->grp) {
774 (struct attribute *) sysfs_attrib); 786 struct kobject *newkobj = &sysfs_attrib->grp->kobj;
787
788 debugf0("%s() grp %s\n", __func__,
789 sysfs_attrib->grp->name);
790
791 edac_remove_mci_instance_attributes(
792 sysfs_attrib->grp->mcidev_attr, newkobj);
793
794 kobject_put(newkobj);
795 } else if (sysfs_attrib->attr.name) {
796 debugf0("%s() file %s\n", __func__,
797 sysfs_attrib->attr.name);
798 sysfs_remove_file(kobj, &sysfs_attrib->attr);
799 } else
800 break;
775 sysfs_attrib++; 801 sysfs_attrib++;
776 } 802 }
777} 803}
@@ -806,7 +832,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
806 * then create them now for the driver. 832 * then create them now for the driver.
807 */ 833 */
808 if (mci->mc_driver_sysfs_attributes) { 834 if (mci->mc_driver_sysfs_attributes) {
809 err = edac_create_mci_instance_attributes(mci); 835 err = edac_create_mci_instance_attributes(
836 mci->mc_driver_sysfs_attributes,
837 &mci->edac_mci_kobj);
810 if (err) { 838 if (err) {
811 debugf1("%s() failure to create mci attributes\n", 839 debugf1("%s() failure to create mci attributes\n",
812 __func__); 840 __func__);
@@ -841,7 +869,8 @@ fail1:
841 } 869 }
842 870
843 /* remove the mci instance's attributes, if any */ 871 /* remove the mci instance's attributes, if any */
844 edac_remove_mci_instance_attributes(mci); 872 edac_remove_mci_instance_attributes(
873 mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj);
845 874
846 /* remove the symlink */ 875 /* remove the symlink */
847 sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK); 876 sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK);
@@ -875,8 +904,8 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
875 debugf0("%s() remove_mci_instance\n", __func__); 904 debugf0("%s() remove_mci_instance\n", __func__);
876 905
877 /* remove this mci instance's attribtes */ 906 /* remove this mci instance's attribtes */
878 edac_remove_mci_instance_attributes(mci); 907 edac_remove_mci_instance_attributes(mci->mc_driver_sysfs_attributes,
879 908 &mci->edac_mci_kobj);
880 debugf0("%s() unregister this mci kobj\n", __func__); 909 debugf0("%s() unregister this mci kobj\n", __func__);
881 910
882 /* unregister this instance's kobject */ 911 /* unregister this instance's kobject */