diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-23 15:26:09 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-10 10:45:01 -0400 |
| commit | 9fa2fc2e2d641df7d69dc4e06cf2552c44b58e95 (patch) | |
| tree | 2fdcdf1b688d006f0c4b99076ff242b1f8b5063b | |
| parent | 4af91889e02c9933823ca8c62fc6f05dfd15f3bd (diff) | |
edac_core: Allow the creation of sysfs groups
Currently, all sysfs nodes are stored at /sys/.*/mc. (regex)
However, sometimes it is needed to create attribute groups.
This patch extends edac_core to allow groups creation.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/edac/edac_core.h | 12 | ||||
| -rw-r--r-- | drivers/edac/edac_mc_sysfs.c | 83 |
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 | ||
| 344 | struct 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 | */ |
| 348 | struct mcidev_sysfs_attribute { | 355 | struct 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 | */ |
| 734 | static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci) | 735 | static 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 | */ |
| 762 | static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci) | 779 | static 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 */ |
