mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
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>
This commit is contained in:
parent
4af91889e0
commit
9fa2fc2e2d
@ -341,12 +341,22 @@ struct csrow_info {
|
|||||||
struct channel_info *channels;
|
struct channel_info *channels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mcidev_sysfs_group {
|
||||||
|
const char *name;
|
||||||
|
struct mcidev_sysfs_attribute *mcidev_attr;
|
||||||
|
struct kobject kobj;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* mcidev_sysfs_attribute structure
|
/* mcidev_sysfs_attribute structure
|
||||||
* used for driver sysfs attributes and in mem_ctl_info
|
* used for driver sysfs attributes and in mem_ctl_info
|
||||||
* sysfs top level entries
|
* sysfs top level entries
|
||||||
*/
|
*/
|
||||||
struct mcidev_sysfs_attribute {
|
struct mcidev_sysfs_attribute {
|
||||||
struct attribute attr;
|
struct attribute attr;
|
||||||
|
|
||||||
|
struct mcidev_sysfs_group *grp;
|
||||||
|
|
||||||
ssize_t (*show)(struct mem_ctl_info *,char *);
|
ssize_t (*show)(struct mem_ctl_info *,char *);
|
||||||
ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
|
ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
|
||||||
};
|
};
|
||||||
|
@ -728,26 +728,43 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* edac_create_mci_instance_attributes
|
* edac_create_mci_instance_attributes
|
||||||
* create MC driver specific attributes at the topmost level
|
* create MC driver specific attributes bellow an specified kobj
|
||||||
* directory of this mci instance.
|
* This routine calls itself recursively, in order to create an entire
|
||||||
|
* object tree.
|
||||||
*/
|
*/
|
||||||
static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci)
|
static int edac_create_mci_instance_attributes(
|
||||||
|
struct mcidev_sysfs_attribute *sysfs_attrib,
|
||||||
|
struct kobject *kobj)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct mcidev_sysfs_attribute *sysfs_attrib;
|
|
||||||
|
|
||||||
/* point to the start of the array and iterate over it
|
while (sysfs_attrib) {
|
||||||
* adding each attribute listed to this mci instance's kobject
|
if (sysfs_attrib->grp) {
|
||||||
*/
|
struct kobject *newkobj = &sysfs_attrib->grp->kobj;
|
||||||
sysfs_attrib = mci->mc_driver_sysfs_attributes;
|
debugf0("%s() grp %s\n", __func__,
|
||||||
|
sysfs_attrib->grp->name);
|
||||||
|
|
||||||
|
err = kobject_init_and_add(newkobj, NULL,
|
||||||
|
kobj,
|
||||||
|
sysfs_attrib->grp->name);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = edac_create_mci_instance_attributes(
|
||||||
|
sysfs_attrib->grp->mcidev_attr, newkobj);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
} else if (sysfs_attrib->attr.name) {
|
||||||
|
debugf0("%s() file %s\n", __func__,
|
||||||
|
sysfs_attrib->attr.name);
|
||||||
|
|
||||||
|
err = sysfs_create_file(kobj, &sysfs_attrib->attr);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
while (sysfs_attrib && sysfs_attrib->attr.name) {
|
|
||||||
err = sysfs_create_file(&mci->edac_mci_kobj,
|
|
||||||
(struct attribute*) sysfs_attrib);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
sysfs_attrib++;
|
sysfs_attrib++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,19 +776,28 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci)
|
|||||||
* remove MC driver specific attributes at the topmost level
|
* remove MC driver specific attributes at the topmost level
|
||||||
* directory of this mci instance.
|
* directory of this mci instance.
|
||||||
*/
|
*/
|
||||||
static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci)
|
static void edac_remove_mci_instance_attributes(
|
||||||
|
struct mcidev_sysfs_attribute *sysfs_attrib,
|
||||||
|
struct kobject *kobj)
|
||||||
{
|
{
|
||||||
struct mcidev_sysfs_attribute *sysfs_attrib;
|
|
||||||
|
|
||||||
/* point to the start of the array and iterate over it
|
|
||||||
* adding each attribute listed to this mci instance's kobject
|
|
||||||
*/
|
|
||||||
sysfs_attrib = mci->mc_driver_sysfs_attributes;
|
|
||||||
|
|
||||||
/* loop if there are attributes and until we hit a NULL entry */
|
/* loop if there are attributes and until we hit a NULL entry */
|
||||||
while (sysfs_attrib && sysfs_attrib->attr.name) {
|
while (sysfs_attrib) {
|
||||||
sysfs_remove_file(&mci->edac_mci_kobj,
|
if (sysfs_attrib->grp) {
|
||||||
(struct attribute *) sysfs_attrib);
|
struct kobject *newkobj = &sysfs_attrib->grp->kobj;
|
||||||
|
|
||||||
|
debugf0("%s() grp %s\n", __func__,
|
||||||
|
sysfs_attrib->grp->name);
|
||||||
|
|
||||||
|
edac_remove_mci_instance_attributes(
|
||||||
|
sysfs_attrib->grp->mcidev_attr, newkobj);
|
||||||
|
|
||||||
|
kobject_put(newkobj);
|
||||||
|
} else if (sysfs_attrib->attr.name) {
|
||||||
|
debugf0("%s() file %s\n", __func__,
|
||||||
|
sysfs_attrib->attr.name);
|
||||||
|
sysfs_remove_file(kobj, &sysfs_attrib->attr);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
sysfs_attrib++;
|
sysfs_attrib++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -806,7 +832,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
|
|||||||
* then create them now for the driver.
|
* then create them now for the driver.
|
||||||
*/
|
*/
|
||||||
if (mci->mc_driver_sysfs_attributes) {
|
if (mci->mc_driver_sysfs_attributes) {
|
||||||
err = edac_create_mci_instance_attributes(mci);
|
err = edac_create_mci_instance_attributes(
|
||||||
|
mci->mc_driver_sysfs_attributes,
|
||||||
|
&mci->edac_mci_kobj);
|
||||||
if (err) {
|
if (err) {
|
||||||
debugf1("%s() failure to create mci attributes\n",
|
debugf1("%s() failure to create mci attributes\n",
|
||||||
__func__);
|
__func__);
|
||||||
@ -841,7 +869,8 @@ fail1:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* remove the mci instance's attributes, if any */
|
/* remove the mci instance's attributes, if any */
|
||||||
edac_remove_mci_instance_attributes(mci);
|
edac_remove_mci_instance_attributes(
|
||||||
|
mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj);
|
||||||
|
|
||||||
/* remove the symlink */
|
/* remove the symlink */
|
||||||
sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK);
|
sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK);
|
||||||
@ -875,8 +904,8 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
|
|||||||
debugf0("%s() remove_mci_instance\n", __func__);
|
debugf0("%s() remove_mci_instance\n", __func__);
|
||||||
|
|
||||||
/* remove this mci instance's attribtes */
|
/* remove this mci instance's attribtes */
|
||||||
edac_remove_mci_instance_attributes(mci);
|
edac_remove_mci_instance_attributes(mci->mc_driver_sysfs_attributes,
|
||||||
|
&mci->edac_mci_kobj);
|
||||||
debugf0("%s() unregister this mci kobj\n", __func__);
|
debugf0("%s() unregister this mci kobj\n", __func__);
|
||||||
|
|
||||||
/* unregister this instance's kobject */
|
/* unregister this instance's kobject */
|
||||||
|
Loading…
Reference in New Issue
Block a user