#include <linux/err.h>
#include <linux/slab.h>
#include <linux/genhd.h>
+#include <linux/mutex.h>
#include "base.h"
#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
.release = class_release,
};
-/* Hotplug events for classes go to the class_obj subsys */
+/* Hotplug events for classes go to the class class_subsys */
static struct kset *class_kset;
{
int error;
if (cls)
- error = sysfs_create_file(&cls->p->subsys.kobj, &attr->attr);
+ error = sysfs_create_file(&cls->p->class_subsys.kobj,
+ &attr->attr);
else
error = -EINVAL;
return error;
void class_remove_file(struct class *cls, const struct class_attribute *attr)
{
if (cls)
- sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr);
+ sysfs_remove_file(&cls->p->class_subsys.kobj, &attr->attr);
}
static struct class *class_get(struct class *cls)
{
if (cls)
- kset_get(&cls->p->subsys);
+ kset_get(&cls->p->class_subsys);
return cls;
}
static void class_put(struct class *cls)
{
if (cls)
- kset_put(&cls->p->subsys);
+ kset_put(&cls->p->class_subsys);
}
static int add_class_attrs(struct class *cls)
}
}
-int class_register(struct class *cls)
+int __class_register(struct class *cls, struct lock_class_key *key)
{
struct class_private *cp;
int error;
if (!cp)
return -ENOMEM;
INIT_LIST_HEAD(&cp->class_devices);
- INIT_LIST_HEAD(&cp->interfaces);
+ INIT_LIST_HEAD(&cp->class_interfaces);
kset_init(&cp->class_dirs);
- init_MUTEX(&cp->sem);
- error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);
+ __mutex_init(&cp->class_mutex, "struct class mutex", key);
+ error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name);
if (error) {
kfree(cp);
return error;
#if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
/* let the block class directory show up in the root of sysfs */
if (cls != &block_class)
- cp->subsys.kobj.kset = class_kset;
+ cp->class_subsys.kobj.kset = class_kset;
#else
- cp->subsys.kobj.kset = class_kset;
+ cp->class_subsys.kobj.kset = class_kset;
#endif
- cp->subsys.kobj.ktype = &class_ktype;
+ cp->class_subsys.kobj.ktype = &class_ktype;
cp->class = cls;
cls->p = cp;
- error = kset_register(&cp->subsys);
+ error = kset_register(&cp->class_subsys);
if (error) {
kfree(cp);
return error;
class_put(cls);
return error;
}
+EXPORT_SYMBOL_GPL(__class_register);
void class_unregister(struct class *cls)
{
pr_debug("device class '%s': unregistering\n", cls->name);
remove_class_attrs(cls);
- kset_unregister(&cls->p->subsys);
+ kset_unregister(&cls->p->class_subsys);
}
static void class_create_release(struct class *cls)
* Note, the pointer created here is to be destroyed when finished by
* making a call to class_destroy().
*/
-struct class *class_create(struct module *owner, const char *name)
+struct class *__class_create(struct module *owner, const char *name,
+ struct lock_class_key *key)
{
struct class *cls;
int retval;
cls->owner = owner;
cls->class_release = class_create_release;
- retval = class_register(cls);
+ retval = __class_register(cls, key);
if (retval)
goto error;
kfree(cls);
return ERR_PTR(retval);
}
+EXPORT_SYMBOL_GPL(__class_create);
/**
* class_destroy - destroys a struct class structure
* We check the return of @fn each time. If it returns anything
* other than 0, we break out and return that value.
*
- * Note, we hold class->sem in this function, so it can not be
+ * Note, we hold class->class_mutex in this function, so it can not be
* re-acquired in @fn, otherwise it will self-deadlocking. For
* example, calls to add or remove class members would be verboten.
*/
if (!class)
return -EINVAL;
- down(&class->p->sem);
+ mutex_lock(&class->p->class_mutex);
list_for_each_entry(dev, &class->p->class_devices, node) {
if (start) {
if (start == dev)
if (error)
break;
}
- up(&class->p->sem);
+ mutex_unlock(&class->p->class_mutex);
return error;
}
*
* Note, you will need to drop the reference with put_device() after use.
*
- * We hold class->sem in this function, so it can not be
+ * We hold class->class_mutex in this function, so it can not be
* re-acquired in @match, otherwise it will self-deadlocking. For
* example, calls to add or remove class members would be verboten.
*/
if (!class)
return NULL;
- down(&class->p->sem);
+ mutex_lock(&class->p->class_mutex);
list_for_each_entry(dev, &class->p->class_devices, node) {
if (start) {
if (start == dev)
} else
put_device(dev);
}
- up(&class->p->sem);
+ mutex_unlock(&class->p->class_mutex);
return found ? dev : NULL;
}
if (!parent)
return -EINVAL;
- down(&parent->p->sem);
- list_add_tail(&class_intf->node, &parent->p->interfaces);
+ mutex_lock(&parent->p->class_mutex);
+ list_add_tail(&class_intf->node, &parent->p->class_interfaces);
if (class_intf->add_dev) {
list_for_each_entry(dev, &parent->p->class_devices, node)
class_intf->add_dev(dev, class_intf);
}
- up(&parent->p->sem);
+ mutex_unlock(&parent->p->class_mutex);
return 0;
}
if (!parent)
return;
- down(&parent->p->sem);
+ mutex_lock(&parent->p->class_mutex);
list_del_init(&class_intf->node);
if (class_intf->remove_dev) {
list_for_each_entry(dev, &parent->p->class_devices, node)
class_intf->remove_dev(dev, class_intf);
}
- up(&parent->p->sem);
+ mutex_unlock(&parent->p->class_mutex);
class_put(parent);
}
EXPORT_SYMBOL_GPL(class_create_file);
EXPORT_SYMBOL_GPL(class_remove_file);
-EXPORT_SYMBOL_GPL(class_register);
EXPORT_SYMBOL_GPL(class_unregister);
-EXPORT_SYMBOL_GPL(class_create);
EXPORT_SYMBOL_GPL(class_destroy);
EXPORT_SYMBOL_GPL(class_interface_register);