Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30e1f7a8 authored by Borislav Petkov's avatar Borislav Petkov Committed by Borislav Petkov
Browse files

EDAC: Export edac sysfs class to users.



Move toplevel sysfs class to the stub and make it available to
non-modularized code too. Add proper refcounting of its users and move
the registration functionality into the reference counting routines.

Signed-off-by: default avatarBorislav Petkov <borislav.petkov@amd.com>
parent 7cfd4a87
Loading
Loading
Loading
Loading
+10 −6
Original line number Original line Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/ctype.h>
#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/edac.h>


#include "edac_core.h"
#include "edac_core.h"
#include "edac_module.h"
#include "edac_module.h"
@@ -235,7 +236,7 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
	debugf1("%s()\n", __func__);
	debugf1("%s()\n", __func__);


	/* get the /sys/devices/system/edac reference */
	/* get the /sys/devices/system/edac reference */
	edac_class = edac_get_edac_class();
	edac_class = edac_get_sysfs_class();
	if (edac_class == NULL) {
	if (edac_class == NULL) {
		debugf1("%s() no edac_class error\n", __func__);
		debugf1("%s() no edac_class error\n", __func__);
		err = -ENODEV;
		err = -ENODEV;
@@ -255,7 +256,7 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)


	if (!try_module_get(edac_dev->owner)) {
	if (!try_module_get(edac_dev->owner)) {
		err = -ENODEV;
		err = -ENODEV;
		goto err_out;
		goto err_mod_get;
	}
	}


	/* register */
	/* register */
@@ -282,6 +283,9 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
err_kobj_reg:
err_kobj_reg:
	module_put(edac_dev->owner);
	module_put(edac_dev->owner);


err_mod_get:
	edac_put_sysfs_class();

err_out:
err_out:
	return err;
	return err;
}
}
@@ -290,12 +294,11 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
 * edac_device_unregister_sysfs_main_kobj:
 * edac_device_unregister_sysfs_main_kobj:
 *	the '..../edac/<name>' kobject
 *	the '..../edac/<name>' kobject
 */
 */
void edac_device_unregister_sysfs_main_kobj(
void edac_device_unregister_sysfs_main_kobj(struct edac_device_ctl_info *dev)
					struct edac_device_ctl_info *edac_dev)
{
{
	debugf0("%s()\n", __func__);
	debugf0("%s()\n", __func__);
	debugf4("%s() name of kobject is: %s\n",
	debugf4("%s() name of kobject is: %s\n",
		__func__, kobject_name(&edac_dev->kobj));
		__func__, kobject_name(&dev->kobj));


	/*
	/*
	 * Unregister the edac device's kobject and
	 * Unregister the edac device's kobject and
@@ -304,7 +307,8 @@ void edac_device_unregister_sysfs_main_kobj(
	 *   a) module_put() this module
	 *   a) module_put() this module
	 *   b) 'kfree' the memory
	 *   b) 'kfree' the memory
	 */
	 */
	kobject_put(&edac_dev->kobj);
	kobject_put(&dev->kobj);
	edac_put_sysfs_class();
}
}


/* edac_dev -> instance information */
/* edac_dev -> instance information */
+6 −3
Original line number Original line Diff line number Diff line
@@ -11,6 +11,7 @@


#include <linux/ctype.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/edac.h>
#include <linux/bug.h>
#include <linux/bug.h>


#include "edac_core.h"
#include "edac_core.h"
@@ -1017,7 +1018,7 @@ int edac_sysfs_setup_mc_kset(void)
	debugf1("%s()\n", __func__);
	debugf1("%s()\n", __func__);


	/* get the /sys/devices/system/edac class reference */
	/* get the /sys/devices/system/edac class reference */
	edac_class = edac_get_edac_class();
	edac_class = edac_get_sysfs_class();
	if (edac_class == NULL) {
	if (edac_class == NULL) {
		debugf1("%s() no edac_class error=%d\n", __func__, err);
		debugf1("%s() no edac_class error=%d\n", __func__, err);
		goto fail_out;
		goto fail_out;
@@ -1028,15 +1029,16 @@ int edac_sysfs_setup_mc_kset(void)
	if (!mc_kset) {
	if (!mc_kset) {
		err = -ENOMEM;
		err = -ENOMEM;
		debugf1("%s() Failed to register '.../edac/mc'\n", __func__);
		debugf1("%s() Failed to register '.../edac/mc'\n", __func__);
		goto fail_out;
		goto fail_kset;
	}
	}


	debugf1("%s() Registered '.../edac/mc' kobject\n", __func__);
	debugf1("%s() Registered '.../edac/mc' kobject\n", __func__);


	return 0;
	return 0;


fail_kset:
	edac_put_sysfs_class();


	/* error unwind stack */
fail_out:
fail_out:
	return err;
	return err;
}
}
@@ -1049,5 +1051,6 @@ int edac_sysfs_setup_mc_kset(void)
void edac_sysfs_teardown_mc_kset(void)
void edac_sysfs_teardown_mc_kset(void)
{
{
	kset_unregister(mc_kset);
	kset_unregister(mc_kset);
	edac_put_sysfs_class();
}
}
+1 −78
Original line number Original line Diff line number Diff line
@@ -26,15 +26,6 @@ EXPORT_SYMBOL_GPL(edac_debug_level);
/* scope is to module level only */
/* scope is to module level only */
struct workqueue_struct *edac_workqueue;
struct workqueue_struct *edac_workqueue;


/*
 * sysfs object: /sys/devices/system/edac
 *	need to export to other files in this modules
 */
static struct sysdev_class edac_class = {
	.name = "edac",
};
static int edac_class_valid;

/*
/*
 * edac_op_state_to_string()
 * edac_op_state_to_string()
 */
 */
@@ -54,60 +45,6 @@ char *edac_op_state_to_string(int opstate)
	return "UNKNOWN";
	return "UNKNOWN";
}
}


/*
 * edac_get_edac_class()
 *
 *	return pointer to the edac class of 'edac'
 */
struct sysdev_class *edac_get_edac_class(void)
{
	struct sysdev_class *classptr = NULL;

	if (edac_class_valid)
		classptr = &edac_class;

	return classptr;
}

/*
 * edac_register_sysfs_edac_name()
 *
 *	register the 'edac' into /sys/devices/system
 *
 * return:
 *	0  success
 *	!0 error
 */
static int edac_register_sysfs_edac_name(void)
{
	int err;

	/* create the /sys/devices/system/edac directory */
	err = sysdev_class_register(&edac_class);

	if (err) {
		debugf1("%s() error=%d\n", __func__, err);
		return err;
	}

	edac_class_valid = 1;
	return 0;
}

/*
 * sysdev_class_unregister()
 *
 *	unregister the 'edac' from /sys/devices/system
 */
static void edac_unregister_sysfs_edac_name(void)
{
	/* only if currently registered, then unregister it */
	if (edac_class_valid)
		sysdev_class_unregister(&edac_class);

	edac_class_valid = 0;
}

/*
/*
 * edac_workqueue_setup
 * edac_workqueue_setup
 *	initialize the edac work queue for polling operations
 *	initialize the edac work queue for polling operations
@@ -153,22 +90,12 @@ static int __init edac_init(void)
	 */
	 */
	edac_pci_clear_parity_errors();
	edac_pci_clear_parity_errors();


	/*
	 * perform the registration of the /sys/devices/system/edac class object
	 */
	if (edac_register_sysfs_edac_name()) {
		edac_printk(KERN_ERR, EDAC_MC,
			"Error initializing 'edac' kobject\n");
		err = -ENODEV;
		goto error;
	}

	/*
	/*
	 * now set up the mc_kset under the edac class object
	 * now set up the mc_kset under the edac class object
	 */
	 */
	err = edac_sysfs_setup_mc_kset();
	err = edac_sysfs_setup_mc_kset();
	if (err)
	if (err)
		goto sysfs_setup_fail;
		goto error;


	/* Setup/Initialize the workq for this core */
	/* Setup/Initialize the workq for this core */
	err = edac_workqueue_setup();
	err = edac_workqueue_setup();
@@ -183,9 +110,6 @@ static int __init edac_init(void)
workq_fail:
workq_fail:
	edac_sysfs_teardown_mc_kset();
	edac_sysfs_teardown_mc_kset();


sysfs_setup_fail:
	edac_unregister_sysfs_edac_name();

error:
error:
	return err;
	return err;
}
}
@@ -201,7 +125,6 @@ static void __exit edac_exit(void)
	/* tear down the various subsystems */
	/* tear down the various subsystems */
	edac_workqueue_teardown();
	edac_workqueue_teardown();
	edac_sysfs_teardown_mc_kset();
	edac_sysfs_teardown_mc_kset();
	edac_unregister_sysfs_edac_name();
}
}


/*
/*
+0 −1
Original line number Original line Diff line number Diff line
@@ -42,7 +42,6 @@ extern void edac_device_unregister_sysfs_main_kobj(
				struct edac_device_ctl_info *edac_dev);
				struct edac_device_ctl_info *edac_dev);
extern int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev);
extern int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev);
extern void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev);
extern void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev);
extern struct sysdev_class *edac_get_edac_class(void);


/* edac core workqueue: single CPU mode */
/* edac core workqueue: single CPU mode */
extern struct workqueue_struct *edac_workqueue;
extern struct workqueue_struct *edac_workqueue;
+7 −3
Original line number Original line Diff line number Diff line
@@ -7,7 +7,7 @@
 *
 *
 */
 */
#include <linux/module.h>
#include <linux/module.h>
#include <linux/sysdev.h>
#include <linux/edac.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/ctype.h>


@@ -354,7 +354,7 @@ static int edac_pci_main_kobj_setup(void)
	/* First time, so create the main kobject and its
	/* First time, so create the main kobject and its
	 * controls and atributes
	 * controls and atributes
	 */
	 */
	edac_class = edac_get_edac_class();
	edac_class = edac_get_sysfs_class();
	if (edac_class == NULL) {
	if (edac_class == NULL) {
		debugf1("%s() no edac_class\n", __func__);
		debugf1("%s() no edac_class\n", __func__);
		err = -ENODEV;
		err = -ENODEV;
@@ -368,7 +368,7 @@ static int edac_pci_main_kobj_setup(void)
	if (!try_module_get(THIS_MODULE)) {
	if (!try_module_get(THIS_MODULE)) {
		debugf1("%s() try_module_get() failed\n", __func__);
		debugf1("%s() try_module_get() failed\n", __func__);
		err = -ENODEV;
		err = -ENODEV;
		goto decrement_count_fail;
		goto mod_get_fail;
	}
	}


	edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
	edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
@@ -403,6 +403,9 @@ static int edac_pci_main_kobj_setup(void)
kzalloc_fail:
kzalloc_fail:
	module_put(THIS_MODULE);
	module_put(THIS_MODULE);


mod_get_fail:
	edac_put_sysfs_class();

decrement_count_fail:
decrement_count_fail:
	/* if are on this error exit, nothing to tear down */
	/* if are on this error exit, nothing to tear down */
	atomic_dec(&edac_pci_sysfs_refcount);
	atomic_dec(&edac_pci_sysfs_refcount);
@@ -429,6 +432,7 @@ static void edac_pci_main_kobj_teardown(void)
			__func__);
			__func__);
		kobject_put(edac_pci_top_main_kobj);
		kobject_put(edac_pci_top_main_kobj);
	}
	}
	edac_put_sysfs_class();
}
}


/*
/*
Loading